Sharing egl Contexts wrt OpenGL ES - c++

One creates an eglContext with:
EGLContext eglCreateContext( EGLDisplay display,
EGLConfig config,
EGLContext share_context,
EGLint const * attrib_list);
The spec allows one to specify a share_context which allows object sharing between the two context.
If one does specify a share_context what exactly is shared (programs, textures, framebuffer objects)? and what exactly remains sandboxed?
Also does this sharing work both ways or only one way?

An extraction from OGL ES 2.0.25 spec (Appendix C:
Shared Objects and Multiple Contexts):
The share list of a context is the group of all contexts which share objects with that context.
Objects that can be shared between contexts on the share list include vertex buffer objects, program and shader objects, renderbuffer objects, and texture objects (except for the texture objects named zero).
It is undefined whether framebuffer objects are shared by contexts on the share list. The framebuffer object namespace may or may not be shared. This means that using the same name for a framebuffer object in multiple contexts on the share list could either result in multiple distinct framebuffer objects, or in a single framebuffer object which is shared. Therefore applications using OpenGL ES should avoid using the same framebuffer object name in multiple contexts on the same share list.

Related

glGenBuffers() object names in different OpenGL contexts

Let's say there is a GUI program with two windows. Each window has its own OpenGL context. There is only one thread.
At some point we want to render stuff in the first and in the second window, so we allocate one buffer for each of the OpenGL contexts with glGenBuffers(1, &buffer_) (among other stuff).
My question is, does the glGenBuffers() function returns unique object names globally, or is it local for each of the OpenGL contexts? In other words, can these two OpenGL contexts have the same object names given by the glGenBuffers()? Apart from object name == 0 of course, which is a special object name.
In case they can, does it mean they share this object name? What would happen if one of the OpenGL contexts deallocates the object by glDeleteBuffers(1, &buffer_)?
Depends if the contexts are in the same share group or not.
See chapter 5 of the OpenGL 4.6 Core Profile specification, "Shared Objects and Multiple Contexts".
The two contexts in my example were not shared (according to genpfault it's the default behavior). Yet, the VBO object names acquired by the glGenBuffers() function were the same in both contexts.
Everything runs smoothly, I can switch between two windows and modify object VBOs presented there (like colors) or their shader uniforms (like camera position)).
I'm using PyQt5 biding for Qt framework and the graphics renderer is Intel(R) UHD Graphics 630.
The program had one QMdiSubWindow with two instances of QMdiSubWindow, each containing one rendered object.
I can only conclude that in this case, when contexts are not shared, object names are unique for the context.

What is shareable between OpenGL contexts and how to enable sharing

I'm making a CAD software that will create different OpenGL contexts for similar view (if they aren't showing the same thing).
I would like to share much data as possible between them OpenGL contexts, especially VBOs and shaders.
I want to know what I can share and how I share them, in a cross-platform way and possibly with plain OpenGL 3.2 (no engine).
The only things OpenGL contexts can share is objects. And even then, "container" objects cannot be shared. Container objects are objects whose primary purpose is to have other objects attached to them. Specifically, the following are container objects:
Framebuffer objects
Vertex array objects
Transform feedback objects
Program pipeline objects
All other objects can be shared.
Sharing objects is a context-based task, usually done either as part of the creation of the context or immediately afterwards. However, since this is done on the context itself, it cannot be a cross-platform operation. OpenGL only defines the behavior of the context, not how to manipulate the context object. The platform-specific APIs responsible for creating and managing contexts handle that: GLX, WGL, EGL, etc.
There are generally two ways this gets handled. One way is for the context creation function to take another context as a parameter; the newly created context will share all sharable objects with the given context. wglCreateContextAttribsARB is the WGL context creation function that takes a context to share with the new one.
The other ways is to use a function immediately after creating the context. This function takes two contexts and shares objects between them. However, you should use such a function immediately after creating the context; you don't want to create objects in the destination context which might conflict with those already in the source. WGL has an older function, wglShareLists, that shares objects between contexts. I know it only talks about display lists, but it shares all sharable objects.
I'm making a CAD software that will create different OpenGL contexts for similar view (if they aren't showing the same thing).
You don't need different contexts for that. OpenGL contexts are not tied to a specific window or drawable. You can bind a OpenGL context to any window/drawable that is pixel format compatible.
I want to know what I can share and how I share them, in a cross-platform way
In general all objects the hold data (textures, vertex/pixel/element objects, renderbuffer objects) are shared, objects that hold state (vertex array object, framebuffer object) are not.
Sharing is setup in Windows either through calling wglShareLists to connect a newly created context to previously existing ones. Or by passing a handle to the context to share with to wglCreateContextAttribsARB; however to obtain a function pointer to that function you first have to create a proxy context (which requires jumping a few hoops, which I've implemented in https://git.datenwolf.net/wglarb/ so you can simply call wglarb_CreateContextAttribsARB without having to care about the rest).
In a X11/GLX environment context sharing has always been set up at context creation time, practically identical to the wglCreateContextAttribsARB way using the glXCreateContext

Are PBOs shared across OpenGL contexts?

Are PBOs or any kind of buffer objects shared across multiple contexts in OpenGL (such as textures)?
My best guess is that NO as the following code is not working:
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, lastFrame->pbo);
glDrawPixels(lastFrame->width, lastFrame->height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
lastFrame->pbo is a buffer which has been created by another GL context. PBO's size is 4*lastFrame->width*lastFrame->height. If instead of binding a PBO I upload data from memory (with the same size), it works fine
The glDrawPixels command is throwing GL_INVALID_OPERATION.
EDIT: lastFrame->pbo is a GLuint and width and height are u_int32_t
EDIT 2: I'm using GLFW for contexts.
The OpenGL specification 4.6 in its Chapter 5 says:
Objects that may be shared between contexts include buffer objects,
program and shader objects, renderbuffer objects, sampler objects,
sync objects, and texture objects (except for the texture objects
named zero).
And
Objects which contain references to other objects include framebuffer,
program pipeline, query, transform feedback, and vertex array objects.
Such objects are called container objects and are not shared.
A Pixel Buffer Object (PBO) is a buffer object. So it is shared.
Your GL_INVALID_OPERATION error may come from not setting as current the context where you use some gl-calls. Or trying to set as current the same context to two different threads at once.
The question is if a PBO object or any kind of buffer object gets shared across multiple contexts in OpenGL (such as textures).
As noted by #Ripi2's answer, the GL spec allows sharing of buffer and texture objects between contexts. But that does not mean that they are automatically shared. You must create shared GL contexts for that to work.
I'm using glfw for contexts
Context sharing is explained in the GLFW documentation.

Trying to understand OpenGL state and objects storage

I am having a hard time understanding what exactly is meant by state. I have read about vertex array objects (VAOs) and vertex buffer objects (VBOs) and as well as context creation. So far i have understood that context is the state of everything associated with the instance of OpenGL that you have created.
I have also understood that a VAO is a reference to the names you created which OpenGL allocated and VBO is the data of those VAOs. However, in the OpenGL red book it says that when you create a VBO that OpenGL allocates a state to the VBO which you obviously have to bind to the VAO.
What I don't understand is relationship between the objects and the context. If the context is supposed to be the state of the OpenGL instance, why does it create additional states which it allocates to the vertex buffer object? Whenever you call some function that changes that state of the context, it actually changes the VBO and not the actual default state of the context.
Have I understood this correctly or am I confusing something here?
The OpenGL context contains all state within your OpenGL instance. The VBOs and VAOs are sub-states within that 'global' state. They cannot exist outside of the GL context (although you could potentially share them with other contexts). When you perform operations on either a VBO or VAO, you are modifying the state of the VBO/VAO, which is a part of the GL context, thus you are modifying it as well.

What does the GL_ARRAY_BUFFER target mean in glBindBuffer?

I was confused about the VBO,
glGenBuffers(1, &positionBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
Besides GL_ARRAY_BUFFER, there are other target types: GL_ATOMIC_COUNTER_BUFFER, GL_COPY_READ_BUFFER...
However, the Opengl manual doesn't mention what these targets mean. I checked the glew.h:
#define GL_ARRAY_BUFFER 0x8892
Does this mean the targets (like GL_ARRAY_BUFFER) are addresses?
What does the target--GL_ARRAY_BUFFER mean in glBindBuffer?
In General
Most OpenGL objects must be bound to locations in the OpenGL context called "targets" for them to be used. A target is nothing more than a place in the context where objects are bound.
Different object types (buffers, textures, etc) have different sets of targets. Generally speaking, each target has a specific meaning: to bind one object to one target means that you want to use that object in whatever manner that target uses objects bound to it.
Binding an object to one target does not affect whether the object is bound to another target (unless it's a texture object; they treat targets differently).
There are functions that modify objects or query data from bound objects. They take a target to which the object they are modifying/querying has been bound.
GL_ARRAY_BUFFER
The GL_ARRAY_BUFFER target for buffer objects represents the intent to use that buffer object for vertex attribute data. However, binding to this target alone doesn't do anything; it's only the call to glVertexAttribPointer (or equivalent functions) that uses whatever buffer was bound to that target for the attribute data for that attribute.
However, the Opengl manual doesn't mention what these targets mean.
OpenGL 2.1 spec, page 38, section 2.9.1: "Vertex Arrays In Buffer Objects"
Does this mean the targets (like GL_ARRAY_BUFFER) are addresses?
Nope, they're just unsigned ints used like enums.