Fixing conflicts between WineD3D and WGL

Ken Thomases ken at
Mon Mar 24 00:48:16 CDT 2014

(Resending with attachments compressed since my previous message doesn't seem to have made it through.  Apologies if anybody receives this twice.)

I have an implementation of WGL_WINE_surface for the Mac driver and modified wined3d to use it.  I still have to implement it for the X11 driver.  I'm sending it along here to let folks see where it's going and review/critique my approach.

I also need to update my description from my original proposal, since things didn't quite work how I planned.  See below.

The attached patches apply on top of the patches I just sent to wine-patches (patches 103407 through 103414).

On Jan 28, 2014, at 6:47 PM, Ken Thomases wrote:

> WGL exposes various pieces of state to the application.  Ideally, WineD3D would not alter any of that state since such alterations are visible to the app and Direct3D doesn't do that on Windows.  …
> * The DC pixel format.  …
> * The current GL context for the thread.  …
> * The DC for the current GL context. …

I realized that another piece of WGL state is the swap interval.  That is set on the window of the current context, not on the context as such.  So, when the context is targeting a surface, the swap interval will instead be set on that surface rather than the window.

> Extension WGL_WINE_surface:
> HANDLE wglCreateSurfaceWINE(HDC hdc, int pixel_format);

This no longer takes a pixel format argument.  Wined3d doesn't have a pixel format chosen at the point where a surface should be created.  Instead, one just calls SetPixelFormat() or wglSetPixelFormatWINE() on a surface DC as is currently done for window DCs.  Similarly, GetPixelFormat() works on a surface DC.  (It shouldn't end up that wglSetPixelFormatWINE() is ever actually called on a surface DC since we won't need to change it after it's first set, but it works.)

Also, instead of using the generic HANDLE type, the extension defines the HSURFACEWINE type.

> Destroying a surface while it still has extant surface DCs results in undefined behavior.

This was untenable given the constraints that wined3d operates under.  The surface is destroyed when the swapchain's window is changed, but there may still be contexts targeting the surface DC.  Those may be current on another thread, so there's no way to clear them and release the DC synchronously.  So, I've made the internal object underlying a surface handle reference counted.  The handle itself holds one reference, which is released when the handle is destroyed.  Each DC obtained by wglGetSurfaceDCWINE() holds an additional reference, which is released during wglReleaseSurfaceDCWINE().


-------------- next part --------------
A non-text attachment was scrubbed...
Name: wgl_wine_surface.tbz
Type: application/octet-stream
Size: 16951 bytes
Desc: not available
URL: <>

More information about the wine-devel mailing list