cginternals / glbinding

A C++ binding for the OpenGL API, generated using the gl.xml specification.
https://glbinding.org
MIT License
829 stars 94 forks source link

glViewport crash on Linux #124

Closed drlight-code closed 8 years ago

drlight-code commented 8 years ago

Hi! Starting off with glbindings. I have my own project with GLFW+glbindings which is just fine. Then there's this external library which does bindings kinda on it's own, failing to provide anything above OpenGL2 (ridiculous). I fixed stuff in their code s.t. native headers aren't included (toggled via a _NO_GLINCLUDES define) and made everything properly typed/consistent. So far so good. I get a runtime exception however when running that code:

ARP: /home/bzk/development/graphics/glbinding/source/glbinding/source/AbstractFunction.cpp:51: glbinding::AbstractFunction::State& glbinding::AbstractFunction::state(int) const: Assertion `pos > -1' failed.

Stacktrace:

#0  0x00007ffff45b35f8 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff45b4a7a in abort () from /usr/lib/libc.so.6
#2  0x00007ffff45ac417 in __assert_fail_base () from /usr/lib/libc.so.6
#3  0x00007ffff45ac4c2 in __assert_fail () from /usr/lib/libc.so.6
#4  0x00007ffff64ed87d in glbinding::AbstractFunction::state (this=0x7ffff6c57640 <glbinding::Binding::Viewport>, pos=-1) at /home/bzk/development/graphics/glbinding/source/glbinding/source/AbstractFunction.cpp:51
#5  0x00007ffff64ed81a in glbinding::AbstractFunction::state (this=0x7ffff6c57640 <glbinding::Binding::Viewport>) at /home/bzk/development/graphics/glbinding/source/glbinding/source/AbstractFunction.cpp:45
#6  0x00007ffff64edcd4 in glbinding::AbstractFunction::address (this=0x7ffff6c57640 <glbinding::Binding::Viewport>) at /home/bzk/development/graphics/glbinding/source/glbinding/source/AbstractFunction.cpp:142
#7  0x00007ffff666d67d in glbinding::Function<void, int, int, int, int>::operator() (this=0x7ffff6c57640 <glbinding::Binding::Viewport>, arguments#0=@0x7fffdf62cd4c: 0, arguments#1=@0x7fffdf62cd48: 0, arguments#2=@0x7fffdf62cd44: 1916, arguments#3=@0x7fffdf62cd40: 1041) at /home/bzk/development/graphics/glbinding/source/glbinding/include/glbinding/Function.hpp:126
#8  0x00007ffff666904c in gl::glViewport (x=0, y=0, width=1916, height=1041) at /home/bzk/development/graphics/glbinding/source/glbinding/source/gl/functions_v.cpp:1885
#9  0x00000000007c6da5 in juce::OpenGLContext::CachedImage::initialiseOnThread (this=0x1158090) at ../../../juce-grapefruit-linux/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:465
#10 0x00000000007c6bef in juce::OpenGLContext::CachedImage::runJob (this=0x1158090) at ../../../juce-grapefruit-linux/modules/juce_opengl/opengl/juce_OpenGLContext.cpp:411
#11 0x000000000051ff27 in juce::ThreadPool::runNextJob (this=0x1179600, thread=...) at ../../../juce-grapefruit-linux/modules/juce_core/threads/juce_ThreadPool.cpp:341
#12 0x000000000055937d in juce::ThreadPool::ThreadPoolThread::run (this=0x11796d0) at ../../../juce-grapefruit-linux/modules/juce_core/threads/juce_ThreadPool.cpp:40
#13 0x000000000051e9a4 in juce::Thread::threadEntryPoint (this=0x11796d0) at ../../../juce-grapefruit-linux/modules/juce_core/threads/juce_Thread.cpp:101
#14 0x000000000051ea0f in juce::juce_threadEntryPoint (userData=0x11796d0) at ../../../juce-grapefruit-linux/modules/juce_core/threads/juce_Thread.cpp:113
#15 0x000000000053a616 in juce::threadEntryProc (userData=0x11796d0) at ../../../juce-grapefruit-linux/modules/juce_core/native/juce_posix_SharedCode.h:852
#16 0x00007ffff6c614a4 in start_thread () from /usr/lib/libpthread.so.0
#17 0x00007ffff466913d in clone () from /usr/lib/libc.so.6

Have built glbindings master debug version, stepped into it, the pos is -1 in that frame.

So I wonder if I'm missing something basic here before I dig further into this. One potential cause of error I see is the following. The project includes, for their custom extension handling, the glx.h header, which in turn includes gl.h. Something was strange with the include order: although I put the glbinding headers before that glx header inclusion, I got redefined symbols in gl.h. I don't quite get that since I thought a second inclusion of gl.h should run against the include guard? Doesn't glbinding set the __glh define in order to avoid this problem? Anyways that's what I did by myself and it seems things don't work as I expect after all.

sbusch42 commented 8 years ago

This might be a multithreading issue, as I notice the threadpool in your callstack. I would suggest to check if all OpenGL calls are made in the same thread in which the OpenGL context was created.

drlight-code commented 8 years ago

Well.. this is a bit tricky. The library (http://juce.com) who just released their new major version this night, makes heavy use of threading in order to render into shared GL contexts for each UI "Component" they provide. Do offscreen FBO rendering in own thread with own (shared) context, then blit all this together finally in the UI thread. The library was developed in the audio context, and it is obvious that they are missing a bit of conceptual understanding regarding GL matters. I've talked to the lead dev, they are to some extent aware of those conceptional problems, however for the time being, this is what I have to deal with. Any advice on how to go about this?

Edit: Checking, doing what you already told me.. Will see if I can dig through this.

drlight-code commented 8 years ago

Still, any idea why the include thing doesn't behave as I expect? Do you think define/undef'ing the include guard before/after glx.h inclusion in their library is a reasonable way to go about this?

scheibel commented 8 years ago

The main issue with multiple contexts in multiple threads regarding glbinding is, that glbinding has to be told which OpenGL context is current for each thread. So it seems like you missed some glbinding::Binding::initialize() and glbinding::Binding::useCurrentContext(). For further explanation, see https://github.com/cginternals/glbinding/wiki/Initialization.

The issue concerning the include of glbinding headers is a more severe one. Basically, glbinding is a total replacement of any other OpenGL header library. This means, that using two or more of them in one cpp file (a compilation unit) leads to semantic and in our case even compilation errors. We suggest you separate the code that needs the original glx headers from those using the glbinding headers.

drlight-code commented 8 years ago

Great advice, went through their framework, identified the context initialization and switching locations, added those calls, and everything is working smoothly now! My include-guard hack seems not to mess anything up as well, since I removed the actual calls to glx for extension queries as well. This needs to be properly cleaned/separated still of course. Thanks for your support and that awesome library of yours! Have a restful night, closing issue.