[waffle] [PATCH 13/18] api: make dl_can_open() dl_sym() display dependent

Emil Velikov emil.l.velikov at gmail.com
Thu Aug 21 05:43:58 PDT 2014

On 20/08/14 23:11, Chad Versace wrote:
> On 08/18/2014 05:35 PM, Emil Velikov wrote:
>> On 18/08/14 22:40, Chad Versace wrote:
>>> On 08/13/2014 03:47 PM, Emil Velikov wrote:
>>>> On 13/08/14 23:23, Chad Versace wrote:
>>>>> On 07/22/2014 08:31 PM, Emil Velikov wrote:
>>>>>> This will allow us to correctly work around waffle design which
>>>>>> allows the a library to be dl_open'ed if we support the corresponding
>>>>>> WAFFLE_CONTEXT (via waffle_display_supports_context_api).
>>>>>> This is required by WGL which (as implemented in this patch) can
>>>>>> support ES contexts via EXT_create_context_es*_profile yet provides
>>>>>> all the symbols via a single library. We should check if ES context
>>>>>> can be create prior rather than blindly trying to retrieve the symbols.
>>>>>> Once waffle has GL dispatch we can remove all the dl functions from
>>>>>> the waffle API, as we'll provide every function that the user needs.
>>>>>> Note that this breaks the API in a non-backwards compatible way.
>>>>>> TODO:
>>>>>>  - Add a note in the release notes.
>>>>>> Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
>>>>>> ---
>>>>> The only remaining patch without review...
>>>>> I don't agree with this patch and think it's unneeded. Perhaps I'm
>>>>> failing to see some subtelty of Windows.
>>>>> Here's my argument. waffle_dl_can_open($LIB_FOR_API) doesn't guarantee
>>>>> that the platform supports $API. It can't. My Linux system, the one I'm
>>>>> typing on right now, supports the following feature matrix according to 
>>>>> wflinfo.
>>>>> platform=gbm                           | GL  GLES1  GLES2  GLES3
>>>>> ---------------------------------------|-----------------------------
>>>>> waffle_dl_can_open                     |  T      T      T      T
>>>>> waffle_display_supports_context_api    |  T      T      T      T
>>>>> Can really create given context type   |  T      T      T      T
>>>>> platform=glx                           | GL  GLES1  GLES2  GLES3
>>>>> ---------------------------------------|-----------------------------
>>>>> waffle_dl_can_open                     |  T      T      T      T
>>>>> waffle_display_supports_context_api    |  T      F      T     *F
>>>>> Can really create given context type   |  T      F      T     *T
>>>>> On my system, GBM supports GLES1 but GLX doesn't. Therefore the ability to
>>>>> obtain functions with dlsym() should be independent of the display in use.
>>>>> This behavior intentionally differs from waffle_get_proc_address().
>>>>> (To make it weirder, waffle_display_supports_context_api(glx_dpy, gles3) returns
>>>>> false despite that the GLX display is actually capable of creating a GLES3 context.
>>>>> This is because Mesa fails to advertise GLX_EXT_create_context_es_profile. This is
>>>>> a Mesa bug, and Waffle needs a workaround for it.)
>>>> Ok let me put things in a different light:
>>>>    The Windows issue:
>>>> All the (GL1.0) symbols come from a single file on Windows - opengl32.dll,
>>>> while at the same time it's the display which knows if we should provide
>>>> symbols for the ES* APIs.
>>>>    The waffle confusion:
>>>> - waffle_dl_can_open
>>>> Handles dlopening a library based on the API requested.
>>>> - waffle_display_supports_context_api
>>>> States what context API can be used but not what API is purely/directly available.
>>>                                                           ^^^^^^^^^^^^^^^
>>> I'm unsure what you mean by "directly" available.
>> purely/directly = not via {W,}GL{,X}_compatibility_you_name_it_extension
>>>> I believe the issue here is dl_can_open is about a file to open, which may not
>>>> always map nicely to "I can get ES* context".
>>> Correct. Just because you can dlopen the OpenGL ES x.y library and get OpenGL ES x.y
>>> symbols does not imply that you can actually create an OpenGL ES x.y context.
>>>> I don't mind dropping the patch although I would appreciate some hints on how
>>>> we can handle the "funny" Windows case.
>>> The Windows case *is* odd. In a perfect world, we should deprecate waffle_dl_can_open()
>>> and waffle_get_proc_address(), and instead replace them with a generic
>>> waffle_get_the_proc_address_the_correct_way_for_this_os_and_context(). Now that
>>> Khronos has published an XML description for the API, it shouldn't be too hard to write
>>> such a function. That's essentially step #1 for any OpenGL dispatch library.
>> We'll get there eventually :P
>>> But... we need to implement Waffle's current weird API for Windows. On Linux, Waffle maps
>>> each API to the library that provides that API's symbols.
>>> Linux:
>>> WAFFLE_DL_OPENGL_ES3		-> libGLESv2 (2 not 3!)
>>> I don't believe that any spec requires libGLESv2 to statically expose the
>>> GLES 3.0 symbols, even if its capable of creating a GLES 3.0 context. I also am
>>> unaware of any spec that forbids libGLESv2 from statically exposing
>>> GLES 3.0 symbols. (Please correct me if I'm wrong). Therefore, libGLESv2 on some Linux/Android
>>> systems may not statically expose GLES 3.0 symbols even if a given EGL/GLXDisplay is capable of
>>> creating a GLES 3.0 context on that libGLESv2. Weird.
>> I believe you are correct. Afaiu the whole idea is to preserve backwards
>> compatibility with ES2, and this seems like a nice way of doing it - don't
>> expose any new symbols to link against/dlsym.
>>> And the same situation holds for s/Linux/Windows/ s/libGLESv2/opengl32.dll/.
>>> Given the above precedent on Linux, I think it makes the most sense to map things
>>> on Windows as below:
>>> Windows:
>>> x = waffle_dl_can_open(WAFFLE_DL_OPENGL);
>>> asert(x == waffle_dl_can_open(WAFFLE_DL_OPENGL_ES1);
>>> asert(x == waffle_dl_can_open(WAFFLE_DL_OPENGL_ES2);
>>> asert(x == waffle_dl_can_open(WAFFLE_DL_OPENGL_ES3);
>> So essentially give the middle finger to ES* under Windows ?
>> Note that it works with this patch - tested with the waffle demos + a couple
>> of piglits.
>>> This behavior feels weird, but it's consistent with the semantics 
>>> of waffle_dl_can_open(): "Can I open the library that provides
>>> the symbols for the desired API?".
>> In order to know what APIs are supported one has to know check for
>> glx_ext_create_context_es*_profile, which is decided/obtained/linked with a
>> display in mind. Thus dl* needs to have a connection to waffle_display in
>> order to to say "OK, I'm allowed to retrieve the symbol glHamBurger for XX API".
> I think now I understand why we see things differently here. The key phrases are
> "to know what what APIs are supported" and "allowed to retrieve symbols". The two
> issues are separate for dynamic symbol loading. Each of dlopen/dlsym [*nix] and
> LoadLibrary/GetProcAddress [Windows] give
> the same result independent of any GLX/EGL/WGL/CGL state. The display is irrelevant.
> If the libary is present, you can open it. Then you *can* query it for symbols.
> Whether you *should* query for glCheeseCake in libGL* or not is a different matter than *can*.
> I don't think waffle should decide to *allow* the app to open the library or query
> for a given symbol. Putting those smarts into Waffle raises additional issues.
> More critically, the existence of wgl/glx_ext_create_context_es_profile does not indicate if the display supports
> GLES 1.0 or GLES 3.0 contexts. The extension only provides a method for the application
> to *request* creation of a specific version of a GLES context. The ability to request does
> imply the ability to create.
> So, even if waffle_dl* took a display parameter on WGL, that display parameter would not
> provide sufficient information to determine if a GLES 1 or 3 were available on that display.
> The display doesn't help here. The display only gives you a reasonable expectation that at
> least one GLES API is supported.
> Like I pointed out above, though. The more critical issue is that, even if you determine
> that the display supports requests for GLES contexts, that still doesn't tell you if
> the library statically exposes any GLES symbols.

Sigh it seems like I had a "too pedantic in the wording used" moment which got
us to this point - truly sorry about that. I will take this as my queue,
especially after the following, which is the I believe summarised it very
nicely from a completely different POV.

> Adding a display parameter to waffle_dl*
> only provides a false sense of security. Waffle really can't know what the library exposes
> without additional information (such as probing the library itself, examining OS and vendor
> info, etc).

Thanks for the detailed explanation

More information about the waffle mailing list