Inserting opengl calls into library runtime

I’m working on the flutter engine which is a library that compiles itself to libflutter_glfw.so. This library can be linked to a C++ program that will render to screen using flutter’s engine, which uses OpenGL through glad.

I modified the engine to accept a generic function call. Then, in my C++ program I created an instance of a function and sent to the engine. This function calls glClearColor(1, 0, 0, 0); just to test. The program crashes.

It’s worth noticing that libflutter_glfw.so does not expose the gl_ functions, therefore I linked my program to glad’s .c file. Although I’m not using the same gl_ functions as libflutter_glfw.so uses, since it’s just C function calls it should work without any problems, shouldn’t it? It doesn’t matter if I’m relinking gl_ functions into a library that already has gl_ private functions. Or does it?

Is a valid context bound to the thread which is making the OpenGL call?

Also: even if you can get a simple case to work, anything non-trivial is likely to be harder as Flutter is probably assuming that the application code isn’t interfering with its context(s). There isn’t really much that you can do without making state changes, and saving the current state (via glGet*) then restoring it later is fragile (and probably inefficient).

Yes, I simply changed this line:

to execute a lambda function. This lambda function calls glClearColor just to test, and the application crashes. I pass the lambda function from outside the thread, from the C++ application which has another glad file linked, different from the libflutter_glfw.so’s glad file, but I don’t think this should be a problem. If the lambda function call is called from a place where normal gl_ calls work, then shouldnt it work? Or does the lambda function has a context of its own, separated from the thread that executes it?

It won’t have a different context, but there may be two sets of GLAD state. If the glad_* symbols aren’t being exported, that’s likely (if they are exported, then the loader will merge duplicate symbols). Are you initialising the copy of GLAD in the application?

Realistically, the best solution is likely to be to build everything with debug symbols and run the application under a debugger to find out what’s actually going on.

nm libflutter_linux_glfw.so | grep glTexImage2D

  00000000034e87a0 b glad_glTexImage2D
  00000000034e87a8 b glad_glTexImage2DMultisample

I inspected and indeed verified that the glad symbols are private (before that I tried linking to libflutter and it complained about glClearColor not existing so it also confirms).

What do you mean by initializing?

Do you mean

if (!gladLoadGL((GLADloadfunc)glfwGetProcAddress))
		{
			std::cout << "Failed to initialize GLAD" << std::endl;
		}

? I tried that and it fails. I tried adding glfwMakeContextCurrent(glfwGetCurrentContext()); before it but I get

X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  130 (MIT-SHM)
  Minor opcode of failed request:  3 (X_ShmPutImage)
  Value in failed request:  0x340
  Serial number of failed request:  157
  Current serial number in output stream:  158

I think it’s because there’s no glfw context. But I shouldn’t create one, should I? It’ll create another window, I don’t want that.

Indeed I think initialization is needed, without it it seems reasonable that the program crashes, it maybe tries to execute the function on an unitialized context.

You shouldn’t create another context. The application would need to call gladLoadGL or gladLoadGLLoader once the library has created and bound the context.

OTOH, you may not even need GLAD on Linux. It’s fairly common for libGL to export the entire OpenGL API directly, in which case you only need to obtain function pointers via glXGetProcAddress for driver-specific extensions or core functions from a newer OpenGL version than that exported by the library.

I didint undestand your first paragraph. Once the library has crated the context, I should call gladLoadGL, but with what arguments? And are you sure that my application can load a context from a library that is totally isolated from it?

For your second paragraph, I tried the following:

PFNGLTEXIMAGE2DPROC glTexImage2D_; //in the h file

...

glTexImage2D_ = (PFNGLTEXIMAGE2DPROC) glXGetProcAddress((const GLubyte*)"glTexImage2D");

glTexImage2D_(GL_TEXTURE_2D, 0, GL_RGBA, width,
                 height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 rgb_buffer_.get());

and I get

X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  130 (MIT-SHM)
  Minor opcode of failed request:  3 (X_ShmPutImage)
  Value in failed request:  0x340
  Serial number of failed request:  157
  Current serial number in output stream:  158

gladLoadGL doesn’t take any arguments. gladLoadGLLoader takes a pointer to a function such as glXGetProcAddress which obtains a function pointer from a string.

The context is thread state. Once the context has bound, you can call OpenGL (and GLX) functions. You don’t need to be able to get a reference to the context unless you’re planning on binding it yourself.

You may not even need that. Have you tried just including <GL/gl.h> and calling glTexImage2D directly?

As for the error: have you created and bound the texture you’re uploading data to?

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.