user32: Track the number of GL surfaces for a window rather than the pixel format.

Ken Thomases ken at codeweavers.com
Wed May 7 15:50:08 CDT 2014


On May 7, 2014, at 8:10 AM, Alexandre Julliard wrote:

> I don't see why D3D would need anything like that.

I'm not sure if you followed the "Fixing conflicts between WineD3D and WGL" thread.  That explains it along with some of the bugs that were known at the time.  Since that thread was started, we've identified more bugs (not necessarily new ones) that my patches fix.

> Do you really need to
> be able to set a new pixel format but still draw with the old one and
> expect the output to be visible?

I am not aware of anything which tries to draw simultaneously using WGL and D3D or two D3D devices/swapchains targeting the same window.  But there are definitely apps which care that GetPixelFormat() continues to return the WGL value even while a D3D swapchain is set up to target the same window, for example.


> It seems to me all you really want is to restore the pixel format after
> D3D has used it, to avoid messing up WGL.

Wined3d is already restoring the pixel format, but it caused a bunch of regressions.  Wined3d needs to "restore" things every time a call into it returns back to the caller, not just when the device and swapchain are torn down.  There's no guarantee that an app won't try to do WGL stuff while a swapchain is set up, even if it's not actually rendering to both simultaneously.  With the X11 driver, that restore is expensive and causes X windows to be destroyed and recreated, which causes rendering failures.

The proper solution is for D3D to target a different object which maintains separate metadata.

> This may require the driver to
> maintain a separate D3D pixel format, and possibly two surfaces, or
> maybe one surface recreated as needed once the app uses WGL again, but I
> don't see why it would justify adding an API to manage an arbitrary
> number of surfaces.

I already explained.  In the multi-threaded case, one thread can still be using an old surface after another thread released it and created a new one.

Beyond that, although I'm not aware of a case where an app uses two D3D devices to target the same window, I'm also not seeing anything in the docs which says it's not allowed.  For example, IDirect3DSwapChain9::Present() takes an hDestWindowOverride parameter which causes that particular present to target a window that was previously unrelated to the swapchain.  I see nothing in the docs that suggest there's a limitation on which window you can use (other than that it be visible or top-level).  No error code meaning "invalid window" or "window format mismatch".

In any case, once you have support for two surfaces, you're already supporting multiple surfaces.  The code would not be especially (any?) simpler if it were limited to one WGL surface and one D3D surface per window.

-Ken




More information about the wine-devel mailing list