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

gg: fix of issue ##21610 #22952

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

gg: fix of issue ##21610 #22952

wants to merge 1 commit into from

Conversation

hedgeg0d
Copy link

@hedgeg0d hedgeg0d commented Nov 23, 2024

Adding fontstash buffer cleanup when processing resize event. Increasing buffer size to 2048x2048.

Huly®: V_0.6-21394

Added fontstash buffer cleanup when processing resize event. Buffer size increased to 2048x2048.
@@ -418,6 +418,7 @@ fn gg_event_fn(ce voidptr, user_data voidptr) {
if ctx.config.resized_fn != unsafe { nil } {
ctx.config.resized_fn(e, ctx.config.user_data)
}
C.fonsResetAtlas(ctx.ft.fons, 2048, 2048)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should that happen on every resize event, and not just once?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the font size may change after every resize event

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may as well not change too - that is specific to the user code.
examples/gg/minimal.v for example or examples/gg/raycaster.v, do not scale their fonts on each resize event.

I think that calling that indiscriminately, while the user drags the border of the window will be too slow for no good benefit 🤔 .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that a better approach would be to use this:

pub fn (s &Context) set_error_callback(callback fn (voidptr, int, int), uptr voidptr) {
    C.fonsSetErrorCallback(s, callback, uptr)
}

so that we can hook into the situations, where the atlas becomes unusable, and reset it only in those cases.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that the window size does not change so often that it somehow significantly affects performance, but this bug really makes itself felt in applications where a lot of labels are rendered at the same time, especially in large font (the buffer stores pixels, so the larger the font, the faster it overflows). But if this is important, maybe it's worth just increasing the buffer size without clearing it?

Copy link
Member

@spytheman spytheman Nov 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try for example v run examples/gg/minimal.v on master and on this PR to see the effect (while resizing with dragging the border slowly).

Copy link
Author

@hedgeg0d hedgeg0d Nov 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, i don't know how to cast voidptr to C.FONScontext. How do I do this?

pub fn (s &C.FONScontext) set_error_callback(callback fn (voidptr, int, int), uptr voidptr) {
    C.fonsSetErrorCallback(s, callback, uptr)
}

pub fn clear_atlas_callback(uptr voidptr, error int, val int) {
	ft := C.FONScontext{uptr} // doesn't work
	fons := ft.fons
	C.fonsResetAtlas(fons, 512, 512)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, i don't know how to cast voidptr to C.FONScontext. How do I do this?

pub fn (s &C.FONScontext) set_error_callback(callback fn (voidptr, int, int), uptr voidptr) {
    C.fonsSetErrorCallback(s, callback, uptr)
}

pub fn clear_atlas_callback(uptr voidptr, error int, val int) {
	ft := C.FONScontext{uptr} // doesn't work
	fons := ft.fons
	C.fonsResetAtlas(fons, 512, 512)
}

&C.FONScontext(uptr)

Copy link
Author

@hedgeg0d hedgeg0d Nov 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I made a callback to clear the buffer when it's full, but now I'm getting messages from sokol:

sokol.memory.slog | user_data: (nil), const_tag: sg, level: 0, item_id: 298, fname: sokol_gfx.h, line: 16102, message: VALIDATION_FAILED: validation layer checks failed
sokol.memory.slog | user_data: (nil), const_tag: sg, level: 1, item_id: 270, fname: sokol_gfx.h, line: 16874, message: VALIDATE_ABND_FS_IMG_EXISTS: sg_apply_bindings: image bound to fragment stage no longer alive
sokol.memory.slog | user_data: (nil), const_tag: sg, level: 0, item_id: 298, fname: sokol_gfx.h, line: 16102, message: VALIDATION_FAILED: validation layer checks failed
sokol.memory.slog | user_data: (nil), const_tag: sg, level: 1, item_id: 270, fname: sokol_gfx.h, line: 16874, message: VALIDATE_ABND_FS_IMG_EXISTS: sg_apply_bindings: image bound to fragment stage no longer alive
sokol.memory.slog | user_data: (nil), const_tag: sg, level: 0, item_id: 298, fname: sokol_gfx.h, line: 16102, message: VALIDATION_FAILED: validation layer checks failed

Code(vlib/gg/text_rendering.c.v):

pub fn (s &C.FONScontext) set_error_callback(callback fn (voidptr, int, int), uptr voidptr) {
    C.fonsSetErrorCallback(s, callback, uptr)
}

pub fn clear_atlas_callback(uptr voidptr, error int, val int) {
	if error == 1 { // atlas overflow error code
		fons := unsafe{&fontstash.Context(uptr)}
		C.fonsResetAtlas(fons, buff_size, buff_size)
	}
}

fn new_ft(c FTConfig) ?&FT {
    ...
    ft := &FT{
		fons:        fons
		font_normal: fons.add_font_mem('sans', bytes, false)
		font_bold:   fons.add_font_mem('sans', bytes_bold, false)
		font_mono:   fons.add_font_mem('sans', bytes_mono, false)
		font_italic: fons.add_font_mem('sans', bytes_italic, false)
		scale:       c.scale
    }
    fons.set_error_callback(clear_atlas_callback, fons)
    return ft
}

But apps works just fine

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the effect of resizing the window in v run examples/gg/minimal.v is gone

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

Successfully merging this pull request may close these issues.

3 participants