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

Author Topic: SFML Context Management  (Read 10741 times)

0 Members and 4 Guests are viewing this topic.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: SFML Context Management
« Reply #15 on: July 03, 2014, 01:52:10 pm »
Telling my users with laptops to update their drivers hoping that it doesn't break something on theirs, isn't really an option either..;
Huh, why not?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #16 on: July 03, 2014, 01:58:26 pm »
Telling my users with laptops to update their drivers hoping that it doesn't break something on theirs, isn't really an option either..;
Huh, why not?

I was somewhat referring to my experience with hp laptops and their lack of support for continuous intel graphic card driver updates - grabbing in an intel graphic driver update from the intel site and just manually installing it to laptops with ex. dual graphic cards, seems many a time to cause a variety of crashes to a finely working machine.

I don't think asking my users to take this risk, especially if my current target audience is one that lacks computer knowledge, is really something I'd like to be doing.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: SFML Context Management
« Reply #17 on: July 03, 2014, 02:14:41 pm »
Quote
I've noticed that the following code works without any access violation issues - any thoughts?
Since you no longer destroy the texture, it's most likely a problem with the destructor of sf::Texture. Which is confirmed by the previous test: calling window.close() would close the window before the texture, whereas letting the objects go out of scope would destroy the texture before the window.
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #18 on: July 03, 2014, 02:29:46 pm »
On second glance, I think it has something to do with context sharing. Perhaps the Intel driver (from back then) doesn't like it when a resource is deleted in a different context than the one it was created in. This is something that works on all current desktop systems and as AlexAUT said, it also works for him with an up-to-date notebook driver. Coding a workaround to make sure that resources are destroyed within the context they were created would become very very complex and is probably not even currently feasible. If it was, it would certainly hamper people that don't have a problem with the current implementation.

You can check if this is the case with this code:
#include <SFML/Graphics.hpp>

int main()
{
    sf::Context context;

    {
        sf::Texture texture;
        texture.create(2, 2);

        // Comment this line to see if it prevents the crash
        context.setActive(false);
    }
}
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #19 on: July 03, 2014, 02:42:26 pm »
On second glance, I think it has something to do with context sharing. Perhaps the Intel driver (from back then) doesn't like it when a resource is deleted in a different context than the one it was created in. This is something that works on all current desktop systems and as AlexAUT said, it also works for him with an up-to-date notebook driver. Coding a workaround to make sure that resources are destroyed within the context they were created would become very very complex and is probably not even currently feasible. If it was, it would certainly hamper people that don't have a problem with the current implementation.

You can check if this is the case with this code:
#include <SFML/Graphics.hpp>

int main()
{
    sf::Context context;

    {
        sf::Texture texture;
        texture.create(2, 2);

        // Comment this line to see if it prevents the crash
        context.setActive(false);
    }
}

Thanks for the reply,

I've just checked the code: as it is, it produces a 'Invalid address specified to RtlFreeHeap( 003F0000, 044EFF30 )' error.
With the 'context.setActive(false)' commented out, the program produces no error.

The code works both without and with the comment with the ATI driver.

What should I be doing then - is there something that can be done on my side?

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: SFML Context Management
« Reply #20 on: July 03, 2014, 02:44:31 pm »
Quote
What should I be doing then - is there something that can be done on my side?

Update graphics drivers as already said, or buy newer hardware which come with better drivers. It isn't feasible for us to work around stupid driver bugs like this.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #21 on: July 03, 2014, 02:46:56 pm »
Quote
What should I be doing then - is there something that can be done on my side?

Update graphics drivers as already said, or buy newer hardware which come with better drivers. It isn't feasible for us to work around stupid driver bugs like this.

Thanks for the opinion,

 But as I've already mentioned, that isn't something I'd really like to be telling my users. If the problem only affected me, sure, that's what I would be doing, but this isn't the case.

I'd like to know if there are any workarounds that can be implemented on my side. I don't mind any excess boilerplate code if that will work.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #22 on: July 03, 2014, 03:00:59 pm »
I hate to break it to you, but if someone is not that computer-savvy, they really shouldn't be getting a system with dual graphics. They are known to be more maintenance intensive (not in the short term, but long term as you already noticed). This can be made easier if the notebook vendor would show some cooperation, but that obviously isn't the case with HP. Ironically, even in this case having a notebook with just an Intel IGP would be easier to maintain, and you could probably still run the latest GL code (albeit probably slower than a single discrete GPU solution) because the driver would be up-to-date.

Sorry to say this, but you're out of luck. We know what the problem is, but the assumption that context sharing works properly is so deeply rooted into the SFML code that it isn't feasible to code a workaround just for people who have this problem, even if they are not that small of a user base.

What you can do however, in your own code, is prevent this case from happening. Now that you understand what triggers the crash, you can take steps to avoid getting into this situation. As should be obvious from the example, make sure you always only have one context active, from the start to the end of the application. The first thing you should do is create the window and set its context active. Do not create new contexts or deactivate it after that. This means, no access to anything graphics related in secondary threads as well. The last thing your application should do is let the window go out of scope after all other resources have already been destroyed. Do not manually close it, it will close itself on destruction.

If you follow those instructions, chances are good that you will end up only working in a single context. I already do this myself, because I constantly work with unsharable resources like VAOs, and this strategy works for me. You have to be very strict on yourself, but if that is the only option you have, I don't think there is anything else you can do.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #23 on: July 03, 2014, 04:27:36 pm »
Sorry to say this, but you're out of luck. We know what the problem is, but the assumption that context sharing works properly is so deeply rooted into the SFML code that it isn't feasible to code a workaround just for people who have this problem, even if they are not that small of a user base.

What you can do however, in your own code, is prevent this case from happening. Now that you understand what triggers the crash, you can take steps to avoid getting into this situation. As should be obvious from the example, make sure you always only have one context active, from the start to the end of the application. The first thing you should do is create the window and set its context active. Do not create new contexts or deactivate it after that. This means, no access to anything graphics related in secondary threads as well. The last thing your application should do is let the window go out of scope after all other resources have already been destroyed. Do not manually close it, it will close itself on destruction.

If you follow those instructions, chances are good that you will end up only working in a single context. I already do this myself, because I constantly work with unsharable resources like VAOs, and this strategy works for me. You have to be very strict on yourself, but if that is the only option you have, I don't think there is anything else you can do.

Thanks for the reply - how should I then handle things like needing to change the window resolution during play? (ex. switching in and out of full screen)

From what I understand of the problem, using RenderWindow.create() to recreate the window may cause a context switch. (or does it not?)
« Last Edit: July 03, 2014, 04:32:20 pm by dk123 »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #24 on: July 03, 2014, 04:37:11 pm »
You remember those good old days where games used to say something like: "To apply these settings, a game restart is required."

Yeah... those days :)
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #25 on: July 03, 2014, 04:46:42 pm »
You remember those good old days where games used to say something like: "To apply these settings, a game restart is required."

Yeah... those days :)

Haha.... those good old days;

I don't know if this would be feasible, but would something along the lines of getting the opengl context from the current window, and managing its lifetime myself be possible? (and would that help solve this)

« Last Edit: July 03, 2014, 04:53:36 pm by dk123 »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #26 on: July 03, 2014, 05:04:05 pm »
No. The window exclusively owns its context and you are not able to access it.

If you want, you can go down the masochistic route and create a second sf::Context which you will always activate after every window operation. Remember: the window will almost always activate its own context when you make it do something. So after every single window.someMethod() call, there would have to be a myContext.setActive(true) call. This second context would need to be declared right after the window to guarantee the destruction order and it would the one that you create all other objects in.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #27 on: July 04, 2014, 06:08:44 am »
If you want, you can go down the masochistic route and create a second sf::Context which you will always activate after every window operation. Remember: the window will almost always activate its own context when you make it do something. So after every single window.someMethod() call, there would have to be a myContext.setActive(true) call. This second context would need to be declared right after the window to guarantee the destruction order and it would the one that you create all other objects in.

Thanks again for the reply,

I'll go with your advice and see how the masochistic route goes. I can confirm that the following code works without problem:

#include <SFML\Graphics.hpp>

int main()
{
        sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );

        sf::Context context;

        sf::Texture texture;
        texture.create( 2, 2 );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        context.setActive( true );
        renderWindow.close();

}
 

But if something like creating a second sf::Context and activating it after every window operation will get the job done, then wouldn't something along the lines of
1. create a function to pass the pointer to a manually managed sf::Context to sf::RenderWindow
2. create a private inline void function within sf::RenderWindow that
'if (m_pUniqueContext != nullptr) m_pUniqueContext->setActive(true)'
3. place the function at the end of every window function (except .close() which will need this at the start)

allow sfml to support both the current shared opengl context implementation and also all use cases requiring a unique opengl context? This seems like a method to get both done with minimum overhead and with barely any change to the current sfml code.

« Last Edit: July 04, 2014, 06:11:47 am by dk123 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: SFML Context Management
« Reply #28 on: July 04, 2014, 08:39:03 am »
1. create a function to pass the pointer to a manually managed sf::Context to sf::RenderWindow
2. create a private inline void function within sf::RenderWindow that
'if (m_pUniqueContext != nullptr) m_pUniqueContext->setActive(true)'
3. place the function at the end of every window function (except .close() which will need this at the start)

allow sfml to support both the current shared opengl context implementation and also all use cases requiring a unique opengl context? This seems like a method to get both done with minimum overhead and with barely any change to the current sfml code.
Maybe it works, just try it. ;)
If this was a suggestion to include it within SFML, then no this is not going to happen.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/