On certain GL drivers on Windows (e.g. those for Intel Arc) we see that
creation of a shared context based on our wrapped WGL context (from
`glutin`) fails with `ERROR_BUSY`:
0:00:00.509113900 29460 000001E07A782CC0 DEBUG glcontext gstglcontext.c:1227:gst_gl_context_create_thread:<glcontextwgl0> Creating thread
0:00:00.509352100 29460 000001E07A782CC0 FIXME glcontext gstglcontext.c:2041:gst_gl_wrapped_context_get_config:<glwrappedcontext0> wrapped context could not retrieve config. The application may be missing a call to gst_gl_context_fill_info() or the specific platform implemention is not implemented for retrieving the config from a wrapped OpenGL context.
0:00:00.543157300 29460 000001E07A782CC0 INFO glcontext gstglcontext_wgl.c:402:gst_gl_context_wgl_choose_format:<glcontextwgl0> chosen config gst-gl-context-config, platform=(GstGLPlatform)GST_GL_PLATFORM_WGL, red-size=(int)8, blue-size=(int)8, green-size=(int)8, alpha-size=(int)8, depth-size=(int)24, stencil-size=(int)8, native-visual-id=(uint)5, surface-type=(GstGLConfigSurfaceType)GST_GL_CONFIG_SURFACE_TYPE_WINDOW;
0:00:00.543770000 29460 000001E07A782CC0 INFO glcontext gstglcontext.c:1322:gst_gl_context_create_thread:<glcontextwgl0> Attempting to create opengl context. user chosen api(s) (any), compiled api support (opengl opengl3) display api (any)
0:00:00.553201100 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:186:gst_gl_context_wgl_create_context: gl context created: 65537
0:00:00.613589500 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:214:gst_gl_context_wgl_create_context:<glcontextwgl0> Available WGL extensions WGL_EXT_depth_float WGL_ARB_buffer_region WGL_ARB_extensions_string WGL_ARB_make_current_read WGL_ARB_pixel_format WGL_ARB_pbuffer WGL_EXT_extensions_string WGL_EXT_swap_control WGL_ARB_multisample WGL_ARB_pixel_format_float WGL_ARB_framebuffer_sRGB WGL_ARB_create_context WGL_ARB_create_context_profile WGL_EXT_pixel_format_packed_float WGL_EXT_create_context_es_profile WGL_EXT_create_context_es2_profile WGL_NV_DX_interop WGL_NV_DX_interop2 WGL_ARB_robustness_application_isolation WGL_ARB_robustness_share_group_isolation WGL_ARB_create_context_robustness WGL_ARB_context_flush_control
0:00:00.614036500 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:235:gst_gl_context_wgl_create_context:<glcontextwgl0> trying to create a GL 4.5 context
0:00:00.631649700 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:235:gst_gl_context_wgl_create_context:<glcontextwgl0> trying to create a GL 4.4 context
0:00:00.650484600 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:235:gst_gl_context_wgl_create_context:<glcontextwgl0> trying to create a GL 4.3 context
0:00:00.669332300 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:235:gst_gl_context_wgl_create_context:<glcontextwgl0> trying to create a GL 4.2 context
0:00:00.687633700 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:235:gst_gl_context_wgl_create_context:<glcontextwgl0> trying to create a GL 4.1 context
0:00:00.706444500 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:235:gst_gl_context_wgl_create_context:<glcontextwgl0> trying to create a GL 4.0 context
0:00:00.725763400 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:235:gst_gl_context_wgl_create_context:<glcontextwgl0> trying to create a GL 3.3 context
0:00:00.745413200 29460 000001E07A782CC0 DEBUG glcontext gstglcontext_wgl.c:235:gst_gl_context_wgl_create_context:<glcontextwgl0> trying to create a GL 3.2 context
0:00:00.781065300 29460 000001E07A782CC0 WARN glcontext gstglcontext.c:1326:gst_gl_context_create_thread:<glcontextwgl0> Failed to create context
0:00:00.781358600 29460 000001E076862100 INFO glcontext gstglcontext.c:1079:gst_gl_context_create:<glcontextwgl0> gl thread created
0:00:00.781584200 29460 000001E076862100 DEBUG glcontext gstglcontext.c:746:gst_gl_context_finalize:<glcontextwgl0> End of finalize
0:00:00.781787700 29460 000001E076862100 WARN glbasefilter gstglbasefilter.c:608:gst_gl_base_filter_find_gl_context_unlocked:<gluploadelement0> error: failed to share contexts through wglShareLists 0xaa
0:00:00.782145700 29460 000001E076862100 INFO glcontext gstglcontext.c:349:gst_gl_context_new: creating a context for display <gldisplay0>, user choice:(null)
0:00:00.782381300 29460 000001E076862100 DEBUG glcontext gstglcontext.c:383:gst_gl_context_new:<glcontextwgl1> Done creating context for display <gldisplay0> (user_choice:(null))
0:00:00.782632900 29460 000001E076862100 DEBUG glcontext gstglcontext.c:1058:gst_gl_context_create:<glcontextwgl1> other_context:<glwrappedcontext0>
0:00:00.782921300 29460 000001E076862100 INFO glwindow gstglwindow.c:295:gst_gl_window_new: creating a window, user choice:(null)
0:00:00.783246300 29460 000001E076862100 DEBUG glcontext gstglcontext.c:956:gst_gl_context_set_window:<glcontextwgl1> window:<glwindowwin32-1>
0:00:00.783815200 29460 000001E07A782D00 DEBUG glcontext gstglcontext.c:1227:gst_gl_context_create_thread:<glcontextwgl1> Creating thread
0:00:00.784130000 29460 000001E07A782D00 FIXME glcontext gstglcontext.c:2041:gst_gl_wrapped_context_get_config:<glwrappedcontext0> wrapped context could not retrieve config. The application may be missing a call to gst_gl_context_fill_info() or the specific platform implemention is not implemented for retrieving the config from a wrapped OpenGL context.
thread 'main' panicked at examples\src\bin\..\glupload.rs:755:44:
called `Result::unwrap()` on an `Err` value: Received error from /GstPipeline:pipeline0/GstGLSinkBin:glsinkbin0/GstGLUploadElement:gluploadelement0: failed to share contexts through wglShareLists 0xaa (debug: Some("../gst-libs/gst/gl/gstglbasefilter.c(608): gst_gl_base_filter_find_gl_context_unlocked (): /GstPipeline:pipeline0/GstGLSinkBin:glsinkbin0/GstGLUploadElement:gluploadelement0"))
This happens because the context is made "current" inside
the `winit` loop before asynchronous GL initialization inside
GStreamer creates a shared context for contexts replied to
`NeedContext("gst.gl.app_context")`. `wglShareLists()` requires neither
context to be current on separate threads. As we have a `Surface` on
the `glutin` side, we're not uncurrenting it anymore, and instead want
to perform GStreamer initialization up-front without a thread, or on a
separate `GLContext`.
One way to prevent GStreamer from creating yet another context on top
of our wrapped context asynchronously, is by creating a new shared GL
context based on our wrapped (WGL) context ourselves.
By adding that context to `GLDisplay` (that we provide in the
relevant `gst.gl.GLDisplay` context query) instead of via the
`gst.gl.app_context` `NeedContext` query, the underlying initialization
code no longer attempts to create a shared context because it
will use the one from `GLDisplay` directly (specifically in e.g.
`gst_gl_base_filter_find_gl_context_unlocked()`).
The preferred way however is to reply this new shared context to
a `Query` for the `gst.gl.local_context` context, which arbitrary
applications can achieve by inserting a pad probe on one of the pads
in the pipeline. GL elements and functions like the one mentioned above
call into `gst_gl_query_local_gl_context()` which performs this query in
both directions, before reading contexts from `GLDisplay` or ultimately
sending a `NeedContext` message outlined above.
With this patch the initialization flow becomes clear from the logs,
where the above lines that will call `wglShareLists()` are now called
directly when `gl_context.create(wrapped_context)` is called in our
Rust code.
In theory, since `GLContext` tracks whether it is current and on
which thread, the upsteam source should emit an error of sorts when
`wglShareLists()` is called on a thread where this `other_context` in
`gst_gl_context_create(_thread)` was not yet current, to not make such
mistakes go unnoticed as most drivers (i.e. AMD's) seem to not make an
issue out of it.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1486>
For sync action failures, instead of requiring users to report the error
through the Reporter interface, let it pass the detail of the failure into
the ActionError::Error directly and report it in the validate reporting
system automatically.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1265>
Instead of passing a ActionRef to the execute function of validate
action types, pass a borrowed Action. This is required for ASYNC actions
as you need to pass the one action structure around so it can be
`set_done` when the async action is done.
This implies that the action structure won't be mutable anymore, but
using the fact that it is "mutable" in C is not clean and in rust we can
just capture variables to achieve similar results anyway.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1265>