[Bf-committers] EGL_CONTEXT_LOST and GL_ARB_create_context_robustness

Jason Wilkins jason.a.wilkins at gmail.com
Wed Jul 31 09:17:43 CEST 2013

On Tue, Jul 30, 2013 at 11:52 PM, Brecht Van Lommel <
brechtvanlommel at pandora.be> wrote:

> Hi,
> This is basically GPU_state_init I think? Calling that after a context
> loss should enough, there isn't really other state that is assumed to
> be there beyond what is set in that function.

Yes, I had that in another draft of this email, but forgot to mention it
when I updated.  I haven't checked to see if this function is called once
per instance of Blender or once per context.  It seems like it is called
once per instance of Blender, so I'm surprised there aren't any reported
bugs due to new windows not having the default state.  It may be due to the
'wglCopyContext' in Windows, which probably works well enough, but I'm not
sure there is an equivalent call on other systems.

> > 2) No data structure can contain a raw resource identifier, because that
> > resource may disappear and become invalid at any time.  All resources
> need
> > to centrally registered along with a callback function and the data
> needed
> > to restore them.  If the context is lost then this will be caught at the
> > next SwapBuffers and all of the callbacks will be executed, restoring the
> > resources in a newly minted context.
> When you say "at any time" is that only after a swapbuffers? I
> couldn't find the docs explaining when exactly this can happen. If it
> happens in the middle of our drawing code that's going to be tricky,
> but if not it should be doable.
It can be lost at anytime because power management events are asynchronous,
but I think that either OpenGL calls silently fail or they all will
generate a GL_INVALID_OPERATION until the context is restored.

But, I think drawing calls silently failing the first frame after coming
back from an event (say sleep) won't be a problem.  The half drawn
backbuffer from before the event will be gone and the drawing operations
after the event will fail.  Meaning that SwapBuffers will have nothing to
swap anyway and then the restoration code would be run to fix the context
and the next frame will succeed.

The window manager should do a full update after that and the TRIPLE update
mode will have to be reset.

> > Resources include texture objects, vertex array objects, vertex buffer
> > objects, frame buffer objects, etc.  Anything with a Gen/Delete function
> > pair.  Interestingly enough, Blender does a lot of drawing with
> DrawPixels,
> > and those functions would actually keep working just fine after a context
> > loss (but are deprecated and also are not a part of ES...)
> >
> > Since the registered resources can change after being created this means
> > all of the functions for each resource will need to be wrapped so that
> the
> > cached copy of the resource can be updated.
> I don't fully understand this yet, but can't we detect if the context
> is lost after swap buffers and then clear all our opengl data? Things
> like VBOs, shaders and image textures are created as needed in the
> drawing code already. There's a few other things like the icon and
> font textures that might need to be cleared too, but generally it
> seems easier to just clear stuff and let Blender create it on demand
> rather than to create some wrapper. Especially since the wrapper would
> take up memory to store copies of the buffers.

Ah, this is a good insight I didn't realize!  The callbacks are not needed,
only the indirect references.

Let me back up...

If Blender creates a resource ID because the resource has been set to 0 in
the data structure it lives in, then we only need to keep the IDs in a
central location and only give Blender a pointer to them.

As it is now, after a CONTEXT_LOST, there is no way to go find all of the
IDs and set them back to 0, so Blender will just continue on trying to use
the old IDs and the glBind* calls will fail.

So, glGen* calls need to be wrapped so that they give an index or pointer
to centrally managed resource IDs, then on CONTEXT_LOST all of the IDs can
get reset to 0.

If all of the IDs are 0, then Blender will just act like they were never
allocated to begin with.

Of course, this assumes that:

1) All code that uses a GL object ID always checks that it isn't 0 it
before using it and if it is zero, create or recreate the object.

2) That all code using IDs never use the IDs directly, but instead uses
something like a gpuGen*/gpuBind*/gpuDelete*

Something like a global flag won't work because there isn't any guarantee
that all lost resources will get recreated in a single frame because the
code path that would recreate them might not get executed.

If Blender was C++ I'd say create a class to hold object IDs.  It could
probably be made completely transparent.  But alas ;-)

> Brecht.
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers

More information about the Bf-committers mailing list