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

Author Topic: Experimental internal-context-less branch  (Read 25219 times)

0 Members and 1 Guest are viewing this topic.

ekun

  • Newbie
  • *
  • Posts: 28
    • View Profile
    • Vagante
    • Email
Re: Experimental internal-context-less branch
« Reply #30 on: April 18, 2016, 10:50:50 pm »
I tried out this branch, and I've run into a deadlock when creating two RenderTextures in different threads. Here's my attempt of a minimal example that recreates the issue on my machine:

#include <SFML/Graphics.hpp>
void createSomeTextures()
{
    for (unsigned i = 0; i < 100; i++)
    {
        sf::RenderTexture texture;
        texture.create(100, 100);
        printf("Thread: %d\n", i);
    }
}
int main(int argc, char** argv)
{
    sf::Thread thread(&createSomeTextures);
    thread.launch();

    for (unsigned i = 0; i < 100; i++)
    {
        sf::RenderTexture texture;
        texture.create(100, 100);
        printf("Main: %d\n", i);
    }
    thread.wait();
    return 0;
}

Apologies if this has already been addressed elsewhere.
@ekunenuke

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Experimental internal-context-less branch
« Reply #31 on: April 18, 2016, 11:46:08 pm »
Can not reproduce here. What's your specs etc?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

ekun

  • Newbie
  • *
  • Posts: 28
    • View Profile
    • Vagante
    • Email
Re: Experimental internal-context-less branch
« Reply #32 on: April 18, 2016, 11:53:24 pm »
Compiled using MSVC 2015 on Windows 10.

Main call stack:
Code: [Select]
> sfml-system-d-2.dll!sf::priv::MutexImpl::lock() Line 52 C++
  sfml-system-d-2.dll!sf::Mutex::lock() Line 57 C++
  sfml-system-d-2.dll!sf::Lock::Lock(sf::Mutex & mutex) Line 39 C++
  sfml-window-d-2.dll!sf::priv::GlContext::setActive(bool active) Line 427 C++
  sfml-window-d-2.dll!sf::priv::GlContext::releaseTransientContext() Line 253 C++
  sfml-window-d-2.dll!sf::GlResource::TransientContextLock::~TransientContextLock() Line 101 C++
  sfml-graphics-d-2.dll!sf::Texture::~Texture() Line 100 C++
  sfml-graphics-d-2.dll!sf::RenderTexture::~RenderTexture() Line 48 C++
  stand.exe!main(int argc, char * * argv) Line 24 C++

Other thread callstack:
Code: [Select]
> sfml-system-d-2.dll!sf::priv::MutexImpl::lock() Line 52 C++
  sfml-system-d-2.dll!sf::Mutex::lock() Line 57 C++
  sfml-system-d-2.dll!sf::Lock::Lock(sf::Mutex & mutex) Line 39 C++
  sfml-window-d-2.dll!sf::priv::GlContext::create() Line 272 C++
  sfml-window-d-2.dll!sf::Context::Context() Line 44 C++
  sfml-graphics-d-2.dll!sf::priv::RenderTextureImplFBO::create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer) Line 88 C++
  sfml-graphics-d-2.dll!sf::RenderTexture::create(unsigned int width, unsigned int height, bool depthBuffer) Line 81 C++
  stand.exe!createSomeTextures() Line 9 C++
  stand.exe!sf::priv::ThreadFunctor<void (__cdecl*)(void)>::run() Line 39 C++
  sfml-system-d-2.dll!sf::Thread::run() Line 83 C++
  sfml-system-d-2.dll!sf::priv::ThreadImpl::entryPoint(void * userData) Line 86 C++

The problematic sections of code seem to be:
GlContext.cpp: Line 264

    Lock lock(mutex);

    GlContext* context = NULL;

    {
        Lock sharedContextLock(sharedContextMutex); // The thread waits until sharedContextMutex.unlock() is called.
 

GlContext.cpp: Line 252
    sharedContext->setActive(false); // This calls Lock lock(mutex), which blocks because other thread has it locked already
    sharedContextLocked = false;
    sharedContextMutex.unlock();
« Last Edit: April 19, 2016, 12:09:16 am by ekun »
@ekunenuke

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Experimental internal-context-less branch
« Reply #33 on: April 20, 2016, 02:55:37 am »
After going over the code with the thread sanitizer, I modified the implementation to make the locking more order independent. Build the latest version of the branch and see if it solves your issue.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

ekun

  • Newbie
  • *
  • Posts: 28
    • View Profile
    • Vagante
    • Email
Re: Experimental internal-context-less branch
« Reply #34 on: April 20, 2016, 03:11:57 am »
Thanks for the update. Trying out the updated branch, I still run into a deadlock, but in a different part of the code.

Here's an updated minimal example that reproduces the issue on my machine:
#include <SFML/Graphics.hpp>
void createSomeTextures()
{
    for (unsigned i = 0; i < 100; i++)
    {
        sf::RenderTexture texture;
        texture.create(100, 100);
        sf::RectangleShape shape({ 50, 50 });
        texture.draw(shape);
        printf("Thread: %d\n", i);
    }
}
int main(int argc, char** argv)
{
    sf::Thread thread(&createSomeTextures);
    thread.launch();

    for (unsigned i = 0; i < 100; i++)
    {
        sf::RenderTexture texture;
        texture.create(100, 100);
        sf::RectangleShape shape({ 50, 50 });
        texture.draw(shape);
        printf("Main: %d\n", i);
    }
    thread.wait();
    return 0;
}

And the locked callstack:
Code: [Select]
> sfml-system-d-2.dll!sf::priv::MutexImpl::lock() Line 52 C++
  sfml-system-d-2.dll!sf::Mutex::lock() Line 57 C++
  sfml-system-d-2.dll!sf::Lock::Lock(sf::Mutex & mutex) Line 39 C++
  sfml-window-d-2.dll!sf::priv::GlContext::setActive(bool active) Line 423 C++
  sfml-window-d-2.dll!sf::Context::setActive(bool active) Line 60 C++
  sfml-window-d-2.dll!sf::Context::~Context() Line 53 C++
  [External Code]
  sfml-graphics-d-2.dll!sf::priv::RenderTextureImplFBO::~RenderTextureImplFBO() Line 68 C++
  [External Code]
  sfml-graphics-d-2.dll!sf::RenderTexture::~RenderTexture() Line 47 C++
  stand.exe!createSomeTextures() Line 11 C++
@ekunenuke

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Experimental internal-context-less branch
« Reply #35 on: April 24, 2016, 12:07:05 pm »
Try out the latest version I pushed, should be fixed there.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

ekun

  • Newbie
  • *
  • Posts: 28
    • View Profile
    • Vagante
    • Email
Re: Experimental internal-context-less branch
« Reply #36 on: April 25, 2016, 11:00:14 pm »
I'm not able to reproduce any deadlocks with the latest version, nice work.

I'll be doing some more testing of this branch on some non-trivial code today, but it looks good so far for the cases I think of at least.
@ekunenuke

ekun

  • Newbie
  • *
  • Posts: 28
    • View Profile
    • Vagante
    • Email
Re: Experimental internal-context-less branch
« Reply #37 on: April 26, 2016, 08:30:49 pm »
I ran into another deadlock with this branch. It didn't occur on my machine so I can't reproduce it unfortunately, but if/when I have more details I'll add them.
@ekunenuke

BlueCobold

  • Full Member
  • ***
  • Posts: 105
    • View Profile
Re: Experimental internal-context-less branch
« Reply #38 on: October 10, 2016, 08:30:30 am »
OK, so, since this is live now, I'm getting the following log-output when creating a simple RenderWindow on Android:

E/libEGL(2065): call to OpenGL ES API with no current context (logged once per thread)
    sf::RenderWindow m_screen;
    m_screen.create(sf::VideoMode(width, height, 32), "...", sf::Style::Fullscreen);

If I afterwards try to use glLoadGen, I get no valid return values from the calls (glGetError always returns 0, glGetString(GL_VERSION) returns 0, glGetIntegerv(GL_MAJOR_VERSION, &v) writes nothing to v, etc):
    sf::RenderWindow m_screen;
    m_screen.create(sf::VideoMode(width, height, 32), "...", sf::Style::Fullscreen);
    m_screen.setActive(true);
    gl::sys::LoadFunctions();
    int maxTextureSize = 0;
    gl::GetIntegerv(gl::MAX_TEXTURE_SIZE, &maxTextureSize);

If, however, I create a RenderTexture after creating the window and before using glLoadGen, glLoadGen works properly, but I'm still getting the error log about missing GL-context. Looks like there's something broken now.
« Last Edit: October 10, 2016, 09:08:15 am by BlueCobold »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Experimental internal-context-less branch
« Reply #39 on: October 11, 2016, 01:08:32 am »
I tried to reproduce the problem you described. I don't get any output in the debug console. An Android maintainer will have to look into this. It seems like there are still a few things bugged in the Android implementation that weren't obvious before.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

BlueCobold

  • Full Member
  • ***
  • Posts: 105
    • View Profile
Re: Experimental internal-context-less branch
« Reply #40 on: November 01, 2016, 01:40:44 pm »
Having the same issue on Windows too since this merge (the issue of glLoadGen being broken, not the issue of missing context). However, the workaround  of using a RenderTexture does not help. glLoadGen returns only 0 on Windows. That's true for gl::MAX_TEXTURE_SIZE, gl::VERSION and gl::EXTENSIONS.

I'm having the very same issues using the default gl-Implementations (meaning not glLoadGen, but simply importing SFML/OpenGL.hpp) like "glGetString" or "glGetIntegerv". Does the provided SFML-OpenGL-example still work?
I'm getting this on Windows:
Failed to activate the window's context
Failed to create texture, its internal size is too high (20x20, maximum is 0x0)
Failed to create texture, its internal size is too high (2048x2048, maximum is 0x0)

    sf::RenderWindow m_screen;
    m_screen.create(sf::VideoMode(width, height, 32), "...", sf::Style::Fullscreen);
    m_screen.setActive(true);

    sf::RenderTexture rt;
    rt.create(20, 20, false);
    sf::Texture t;
    t.loadFromFile(filePath);

Is there any minimal example how to successfully use glLoadGen after this feature had been implemented? Or is SFML only broken for me?
« Last Edit: November 01, 2016, 02:59:43 pm by BlueCobold »