-
Notifications
You must be signed in to change notification settings - Fork 533
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
first attempt at updating stb_truetype and stb_rect_pack #53
Conversation
Updated the ttf branch so the stb files are separate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. This is an important step.
In addition to my inline comments, could you also bump Nuklear version, generate new nuklear.h
and include it in this PR?
I'll merge it after my comments got addressed 😉. @SairesArt please take a look at this PR as well.
I've compiled on both macOS and Linux, I have no idea why this 'build failed'. |
Dont know why the build failed for github, it works fine for me on macOS and Linux |
That's weird it compiled for you as the syntax |
On the other hand, I'd still say we should stick with C89 for such core functionality (only demos and backends are allowed to use C99 or newer, but the core |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll then wait for @SairesArt until he looks at what stuff is common in reviews and what to look for when reviewing for this project 😉.
OK, changed the comments to c89... |
@ronaaron I'm a bit reluctant to change the stb libs - I'd really like to have them 1:1. Would you rather change the python script? |
Hey, I need this to work for my own project... |
Different behavior from the previous version of nuklear.h: I get SIGSEGV from stbtt_PackFontRangesGatherRects called by nk_font_atlas_bake from nk_glfw3_font_stash_end. This happens if I have more than 3 or 4 fonts in the atlas. I assume it's due to the allocator, but ...
|
@ronaaron what does Valgrind verbose output say to the SIGSEGV? |
I'm running on macOS, no valgrind available. I tried using ASAN, but it doesn't trip. |
Well, yeah - the Nuklear comment in that function says it all: NK_INTERN int
nk_tt_PackFontRangesGatherRects(struct nk_tt_pack_context *spc,
struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
int num_ranges, struct nk_rp_rect *rects)
{
/* rects array must be big enough to accommodate all characters in the given ranges */
... Is your app open source? If so, could we get it somewhere and run it with Valgrind? If not, you still can quickly run a VM with any mainstream Linux distro 😉. |
It's not open source, sorry. But here's relevant valgrind info: ==19314== Conditional jump or move depends on uninitialised value(s) ==19314== Uninitialised value was created by a heap allocation ==19314== Use of uninitialised value of size 8 ==19314== Invalid read of size 4 |
The problem goes away by increasing the amount of memory allocated in nk_font_baker_memory(). Of course that's not likely the correct solution, but it points in a direction. |
It still works with that fix when I double or triple the number of fonts, so something along those lines is a good fix. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're almost there 😉.
src/nuklear_font.c
Outdated
*temp += (nk_size)total_range_count * sizeof(struct nk_tt_pack_range); | ||
*temp += (nk_size)*glyph_count * sizeof(struct nk_tt_packedchar); | ||
*temp = (nk_size)*glyph_count * sizeof(struct stbrp_rect); | ||
*temp += (nk_size)*glyph_count * sizeof(stbtt_pack_range); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I think we're getting close to merging. But this change from total_range_count
to glyph_count
is overly suspicious to merge it 😢.
I think stb_truetype started using some structs a bit differently in the newer versions. Maybe it's some off-by-one oversight or struct padding or whatever. I'd look at how the structs nk_rp_rect
nk_tt_pack_range
nk_tt_packedchar
stbrp_rect
stbtt_pack_range
stbtt_packedchar
nk_font_bake_data
are being used everywhere and whether they're used everywhere with corresponding counts as I don't think stbtt_pack_range
depends on glyph count, but rather truly on the calculated total_range_count
.
Have you tried just adding temp += 1
or temp += 8
or similar (i.e. a very small fixed number)?
body p { margin-bottom: 0cm; margin-top: 0pt; }
On 10/02/2020 17:41, dumblob wrote:
@dumblob requested changes on this pull request.
We're almost there 😉.
In src/nuklear_font.c:
@@ -2152,9 +137,9 @@ nk_font_baker_memory(nk_size *temp, int *glyph_count,
*glyph_count += nk_range_glyph_count(i->range, range_count);
} while ((i = i->n) != iter);
}
- *temp = (nk_size)*glyph_count * sizeof(struct nk_rp_rect);
- *temp += (nk_size)total_range_count * sizeof(struct nk_tt_pack_range);
- *temp += (nk_size)*glyph_count * sizeof(struct nk_tt_packedchar);
+ *temp = (nk_size)*glyph_count * sizeof(struct stbrp_rect);
+ *temp += (nk_size)*glyph_count * sizeof(stbtt_pack_range);
Overall I think we're getting close to merging. But this change
from to is overly suspicious to merge it 😢.
I think stb_truetype started using some structs a bit
differently in the newer versions. Maybe it's some off-by-one
oversight or struct padding or whatever. I'd look at how the
structs nk_rp_rect nk_tt_pack_range
nk_tt_packedchar stbrp_rect stbtt_pack_range
stbtt_packedchar nk_font_bake_data
are being used everywhere and whether they're used everywhere
with corresponding counts as I don't think stbtt_pack_range
depends on glyph count, but rather truly on the calculated total_range_count.
Have you tried just adding time += 1 or time
+= 8 or similar (i.e. a very small fixed number)?
Yes, and it crashed.
[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "#53?email_source=notifications\u0026email_token=AECUVBSRIDLIS652OCP3U43RCFYSPA5CNFSM4KKHB4HKYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCU4LVCI#pullrequestreview-356039305",
"url": "#53?email_source=notifications\u0026email_token=AECUVBSRIDLIS652OCP3U43RCFYSPA5CNFSM4KKHB4HKYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCU4LVCI#pullrequestreview-356039305",
"name": "View Pull Request"
},
"description": "View this Pull Request on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]
Ron AARON |
CTO Aaron High-Tech, Ltd |
+1 516.373.0794 / +972 52.652.5543 |
GnuPG Key: 91F92EB8
|
I fixed the actual problem with the memory. It needs to zero the allocated memory. |
src/nuklear_font.c
Outdated
@@ -1179,6 +1179,7 @@ nk_font_atlas_bake(struct nk_font_atlas *atlas, int *width, int *height, | |||
tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size); | |||
NK_ASSERT(tmp); | |||
if (!tmp) goto failed; | |||
memset(tmp,0,tmp_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please tabs to spaces and then I'm merging. This is a leap forward for Nuklear. Thanks!
Seems you're online - because of the importance of this change, feel free to also bump version in |
Thanks @ronaaron for the tiresome work! It was totally worth it. Hope you'll become project member at some point - feel free to express your will any time 😉. |
|
||
n = 1+nk_ttUSHORT(endPtsOfContours + numberOfContours*2-2); | ||
m = n + 2*numberOfContours; /* a loose bound on how many vertices we might need */ | ||
vertices = (struct nk_tt_vertex *)alloc->alloc(alloc->userdata, 0, (nk_size)m * sizeof(vertices[0])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The adapted stb_truetype
library in Nuklear used to use the nk_allocator
that nk_font_baker
(which comes from nk_font_atlas
) uses for all its memory allocations.
Removing these customizations, and insisting on not introducing them, has forced the use of separate methods for memory management in stb_truetype
:
#ifndef STBTT_malloc
static nk_handle fictional_handle = {0};
#define STBTT_malloc(x,u) nk_malloc( fictional_handle, 0, x )
#define STBTT_free(x,u) nk_mfree( fictional_handle , x)
#endif
nk_malloc
and nk_mfree
only exist when NK_INCLUDE_DEFAULT_ALLOCATOR
is defined.
So the negative effect of this change is that the library no longer builds when NK_INCLUDE_DEFAULT_ALLOCATOR
is not defined.
This presents a problem for libraries that wrap Nuklear and provide their own memory management, eg many bindings for other languages.
As an example, I am working on updating a binding from a Nuklear version before this PR to a Nuklear version after this PR.
It is preferred to not let Nuklear pull in stdlib for memory management, since the language in question (Rust, but the point of this comment is language-agnostic) can provide its own, and it makes no sense to have two separate ways of managing memory.
This was previously possible by creating a nk_allocator
that points to custom alloc/free implementations that delegate to the language's implementations, and initializing a nk_font_atlas
with this allocator; this allocator would be used for all font-related memory management in Nuklear, including in stb_truetype
.
After this PR, stb_truetype
no longer uses the nk_allocator
of nk_font_atlas
.
This means it must be provided with a separate implementation in the binding code.
This is not technically difficult (just implement a malloc and a free, and alias STBTT_malloc
and STBTT_free
to them), but is certainly cumbersome for the users of this library that actually prefer finer control over memory management (which, given the library's lightweight nature, is more than just those using bindings to other languages).
Additionally, the nk_font_baker
allocator seems to no longer be used for anything.
Another subtle difference is that, once STBTT_malloc
and STBTT_free
are dealt with as above, it is no longer possible to use two nk_font_atlas
with two different allocators at the same time in the same manner as before this change, since stb_truetype
's memory management cannot switch between different allocators at run time (without manually implementing that, and introducing locking for multithreaded accesses if necessary, etc).
Using multiple nk_font_atlas
in the same application simultaneously is not something that I have personally needed so far, and can't immediately think of a reason where this would be needed, but it is certainly worth noting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asoft thanks for coming here and describing in detail what this change caused. What would you suggest we implement/change?
Btw. we're open to PRs (especially those increasing interoperability without much cost), so feel free to make one and we might discuss the details there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If allowing for finer control over mememory management is a goal of Nuklear, I think the current situation around memory management in stb_tt should be treated as a bug.
I'd like this bug to be fixed.
Options I see, in order of perceived implementation difficulty:
- Add configuration to setup stb_tt library-wide to use a given allocator (via an alternative implementation of
STBTT_malloc
andSTBTT_free
). - Propagate
nk_font_atlas
's allocator to stb_tt by modifying Nuklear's copy of stb_tt, adding the allocator parameter in all methods whereSTBTT_malloc
/STBTT_free
are used - Propagate
nk_font_atlas
's allocator to stb_tt orSTBTT_malloc
/STBTT_free
via some other means, without modifying the committed copy of stb_tt
Pros/cons that I see:
- pros: simple to implement; simple to use
cons: introduces yet another place for memory management; has all drawbacks mentioned in initial comment. - pros: simple to implement; simple to use; does not change amount of various memory management entry points
cons: complicates stb_tt version updates - pros: simple to use; does not change amount of various memory management entry points
cons: likely complicated implementation, cannot be implemented immediately, need to research options;
I favor option 3, because it does not have the cons of options 1 and 2.
I'm playing locally with some options, don't have a good solution yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, how about reversing the dependency and propagate stb_tt's STBTT_malloc/STBTT_free
to nk_font_atlas or something along these lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found a simple option 3 solution: #186.
In response to the issue I reported, I forked the repo and pushed my changes to a branch.
The code does compile and it seems to run 'ok' on Linux, but it crashes on macOS because apparently the allocator stuff in the baker percolates around.
I don't understand all the ramifications so I'm asking for someone who knows the code to please assist.