[PATCH v2 1/2] win32u: Don't pass physdev to wine_get_wgl_driver() driver function.

Paul Gofman pgofman at codeweavers.com
Thu Feb 3 16:04:08 CST 2022


On 2/3/22 18:41, Paul Gofman wrote:
> On 2/3/22 17:25, Jacek Caban wrote:
>> Hi Paul,
>>
>> On 2/1/22 18:32, Paul Gofman wrote:
>>> @@ -1347,13 +1349,29 @@ NTSTATUS WINAPI 
>>> NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNE
>>>    */
>>>   struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT 
>>> version )
>>>   {
>>> +    const struct gdi_dc_funcs *driver_funcs[11], **next_funcs;
>>>       struct opengl_funcs *ret = NULL;
>>>       DC * dc = get_dc_ptr( hdc );
>>> +    PHYSDEV physdev;
>>>         if (dc)
>>>       {
>>> -        PHYSDEV physdev = GET_DC_PHYSDEV( dc, wine_get_wgl_driver );
>>> -        ret = physdev->funcs->wine_get_wgl_driver( physdev, version );
>>> +        next_funcs = driver_funcs;
>>> +        physdev = GET_DC_PHYSDEV( dc, wine_get_wgl_driver );
>>> +        while (physdev && next_funcs - driver_funcs < 
>>> ARRAY_SIZE(driver_funcs) - 1)
>>> +        {
>>> +            *next_funcs++ = physdev->funcs;
>>> +            if (physdev->funcs == &null_driver) break;
>>> +            physdev = GET_NEXT_PHYSDEV( physdev, 
>>> wine_get_wgl_driver );
>>> +        }
>>> +        *next_funcs = NULL;
>>> +        next_funcs = driver_funcs;
>>> +        while (*next_funcs)
>>> +        {
>>> +            ret = (*next_funcs)->wine_get_wgl_driver( version, 
>>> &next_funcs );
>>> +            if (ret || !next_funcs) break;
>>> +            ++next_funcs;
>>> +        }
>>
>>
>> If the current PHYSDEV locking does not fit what we need here, it may 
>> be indeed a good idea to use something different here. It seems 
>> unique in this aspect anyway. However, it doesn't seem like hacking 
>> around PHYSDEV pointers like this is really what we need here. You 
>> could, for example, move wine_get_wgl from gdi_dc_funcs to 
>> user_driver_funcs (similar to what 
>> 9596e7f2a4e972c35efdca38b01d068bfc055d36 did for Vulkan) and call it 
>> with no PHYSDEV involved. __wine_get_wgl_driver could look roughly 
>> like this:
>>
>>
>> if ((hwnd = NtUserWindowFromDC( hdc )) && (ret = 
>> user_driver->wine_get_wgl_driver( hwnd, version )) return ret;
>>
>> if (selected correct bitmap on hdc) return get_osmesa_driver( version );
>>
>> return (void *)-1;
>>
>>
>> How does it look to you?
>>
>>
> I am not quite sure, but this looks a bit convoluted to me. First in 
> terms of getting user hwnd from dc (which can work as I understand but 
> brings some dependency on the not directly related locking and logic). 
> Then heuristics in __wine_get_wgl_driver() for guessing if osmesa 
> should be used while currently it is more straightforward as all that 
> knowledge is already incorporated into the driver chain, there is the 
> logic spread elsewhere which controls that.
>
> I realize that hacking out driver function pointers indeed does not 
> look nice. Maybe if getting hwnd is really not an issue (I assume 
> user_callbacks->pWindowFromDC() can be used for that?) we can indicate 
> in the DC structure if osmesa should be used (to be set when the 
> dibdrv is added to device chain not through windrv)? This way we won't 
> be duplicating that logic.
>
I've got another idea. Given we don't actually need anything from the DC 
when getting GL functions from the drivers besides the DC ptr don't get 
freed, can't we just GDI_inc_ref_count() on the DC handle and proceed to 
physdev->funcs->wine_get_wgl_driver() without holding any locks and 
without changing anything in the current physdev drivers?




More information about the wine-devel mailing list