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

Chad Versace chad.versace at linux.intel.com
Wed Aug 20 15:11:13 PDT 2014


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		-> libGL
>> WAFFLE_DL_OPENGL_ES1		-> libGLESv1
>> WAFFLE_DL_OPENGL_ES2		-> libGLESv2
>> 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. 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).


More information about the waffle mailing list