Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Async corrupts Font ?  (Read 4987 times)

0 Members and 1 Guest are viewing this topic.

Dude234

  • Newbie
  • *
  • Posts: 10
    • View Profile
Async corrupts Font ?
« on: July 24, 2018, 10:19:41 am »
(Using: SFML.NET 2.3)

I'm writing a resource loading screen. And I successfully implemented loading with async/await.
Next step is to display the progression. This is done with SFML.Text.

When starting the async, somehow the Font gets corrupted once. The outcome are missing letters in the Font data. The Font is NOT touched in the async chain!

If I recreate the Font after the async has fired its Tasking, everything seems to be fine. 
There are not multiple Tasks in parallel, but only one at a time.

To me, this looks like the .net threading takes memory that is used by the Font?
I do not claim to have a deep understanding of what is happening here.

Here is my code in very reduced form. I test loading with a lot of 5MB bmps currently.
I'm glad if you guys have some ideas on SFML objects and threading. Are they safe ;D

Font font;
Text text;

ctor(){
font = new Font(); //path
text = new Text();
LoadResourcesAsync();
}

async void LoadResourcesAsync() {
await Load();
}

async Task Load(){
foreach
await Task.Run(() => ); //load stuff and report progress via event
}

void Draw(RenderTarget target) {
text.DisplayedString = currentFile; // or percentage (currentFile is updated via event)
target.Draw(text);
}
 
« Last Edit: July 24, 2018, 10:23:47 am by Dude234 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Async corrupts Font ?
« Reply #1 on: July 24, 2018, 10:39:39 am »
SFML 2.3 should behave correctly in this asynchronous scenario. I would expect to see this kind of problem starting from SFML 2.4. Are you sure that your CSFML shared libraries are also in version 2.3? How did you get SFML.Net 2.3 (the latest on the website is 2.2)?
Laurent Gomila - SFML developer

Dude234

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Async corrupts Font ?
« Reply #2 on: July 24, 2018, 11:01:33 am »
Thanks for responding so fast :)

I built 2.3 with the solution provided on the official github.
https://github.com/SFML/SFML.Net/releases

And I am using csfml 2.2 currently :-\ not the best idea ...

I tried combine the csfml 2.3 from the website with the built 2.3, but that did not work.
How can I make csfml and sfml.net 2.3 work?

Dude234

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Async corrupts Font ?
« Reply #3 on: July 24, 2018, 11:12:06 am »
Okay, nevermind about integrating csfml 2.3. I think I got it working.

You can use the version on the website (csfml 2.3) with the built version of sfmlnet 2.3, right?

Now I got some serious Stackoverflow Exceptions happening.
But I cannot say what is causing it for now, need to further investigate.

Dude234

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Async corrupts Font ?
« Reply #4 on: July 24, 2018, 11:47:57 am »
This current setup (csfml 2.3 from website and built sfmlnet 2.3) is super unstable.
Maybe I have combined them the wrong way. This doesnt play together.

I need to Dispose objects before closing the window. But more problematic, sfml objects throw Overflow Exceptions when they get null referenced? And the font corruption exists also as far as I can tell in my bugged code.

Is there a way to to make 2.3 work? Do I need to revert to stable 2.2 and forget about threading?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Async corrupts Font ?
« Reply #5 on: July 24, 2018, 12:34:51 pm »
What you need for asynchronous font loading, is a call to glFlush() after it's done. So if you manage to call that OpenGL function from your C# code, then it should work with any version of SFML.

But as I said, glFlush() was removed from Font::loadFromFile in SFML 2.4, so this shouldn't be a problem with SFML 2.2 or 2.3. Your issue mightbe caused by something else.
Laurent Gomila - SFML developer

Dude234

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Async corrupts Font ?
« Reply #6 on: July 24, 2018, 01:59:58 pm »
You mean something like OpenTK.Graphics.ES11.GL.Flush()? I'm afraid this will not work (Access Violation).

(I completly reverted back to 2.2 for now).
I would still appreciate a guide to use sfmlnet 2.3 with csfml 2.3 though. Thanks!

I made a workaround which recreates the Font everytime the DisplayedString is updated when a Task finishes. This is not optimal and even dangerous since the Font is heavy and memory can spike.
(Adding GC.Collect() helps to keep memory on a normal level but comes with some CPU load).

Alternatively I could avoid threading alltogether and just load a chunk per frame.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Async corrupts Font ?
« Reply #7 on: July 24, 2018, 02:18:31 pm »
OpenTK.Graphics.ES11.GL.Flush() probably wants its own OpenGL context, and cannot use the one set by SFML. An extreme solution would be to dynamically load the OpenGL32.dll file, import its "glFlush" symbol and call it. I don't remember how you do it with .Net but I think it's quite easy.

I'm sorry for the lack of maintenance on CSFML and SFML.Net, maybe you should contact people who actively work on that (see https://en.sfml-dev.org/forums/index.php?topic=24211.0 for example).
Laurent Gomila - SFML developer

Dude234

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Async corrupts Font ?
« Reply #8 on: July 24, 2018, 03:35:48 pm »
[DllImport("opengl32.dll")]
public static extern void glFlush(); //no error when called
public static extern void Test(); //causes error (no entry point found), so I assume the dll is loaded and glFlush is a valid call

I think I got the dllimport working and can call glFlush() now. But nothing happens (beside a small stall). This does not repair the Font.

I don't know how it relates to my problem. My wild guess is, that the memory of the Font gets overwritten or used by another Thread. Then letters disappear.

I actually nailed it down to this (version 2.2): I need to re-create the Font after the async begins and when the async ends. Somehow, both events corrupt the Font object. This is my current observation and I tested a fair amount of it.

Yes, its quite sad, that SFML.NET does not get so much attention and maintenance. I still like it a lot.

And thanks for the link, I got it up and running (sfml.net 2.4 and csfml 2.4) in a test project. But I would like to stick with 2.2 for now.
« Last Edit: July 24, 2018, 03:40:43 pm by Dude234 »