http://bugs.winehq.org/show_bug.cgi?id=2082
--- Comment #138 from Ken Thomases ken@codeweavers.com --- (In reply to comment #136)
- The main thing I'm wondering about is if it wouldn't make more sense to
pass a window to wglCreateFullscreenDCWINE(). Some of the considerations there are what should happen when the device window is e.g. destroyed or minimized.
It seems like knowing how to respond to such events should be the responsibility of ddraw/d3d. The driver can provide the tools necessary for those to implement the proper behavior. If we know what those are, we can add them to the extension.
- If we do want to pass a device name to wglCreateFullscreenDCWINE(), it
should probably take a WCHAR[], and you can get at that from the context as "context->swapchain->device->adapter->DeviceName".
I would have used a WCHAR string but make_opengl doesn't currently know about WCHARs. It could be taught. (Actually, I'd probably use "LPCWSTR" because it's easier to teach make_opengl how to handle that than "const WCHAR*".)
I didn't know about getting the device name. Thanks for that.
- wglDeleteFullscreenDCWINE() seems to just be a wrapper around
DeleteDC(). If possible I think it would be preferable to be able to just call ReleaseDC() on the DC returned by wglCreateFullscreenDCWINE(), and then just use wined3d_release_dc().
Well, DeleteDC() and ReleaseDC() are for different purposes. ReleaseDC() is from user32 and, conceptually, user32 doesn't know anything about the DC provided by the extension and so we shouldn't ask it to release any DCs we didn't get from it (even if ReleaseDC() were a simple wrapper around DeleteDC(), which it's not).
Beyond that, wined3d_release_dc() checks if WindowFromDC() matches the passed-in window and does nothing if not. I'm not aware of any way for the WGL extension to create a DC such that WindowFromDC() returns a window, except by using GetDC() and that defeats the point.
Finally, although the implementation of the extension in the Mac driver is just a thin wrapper around DeleteDC(), I wanted to provide for the possibility that it might not be for some other implementation. That said, the driver does already have a pDeleteDC entry in its GDI function table, so it could put custom cleanup there.
- If we can just use wined3d_release_dc(), context->hdc_fullscreen can
just go away, but otherwise it should probably be part of the other context bitfields like current/destroyed/valid.
Indeed. I just failed to see that group of bitfields.
- When there are multiple threads drawing, wglCreateFullscreenDCWINE() is
going to be called multiple times for the same window / display. I didn't really review the winemac.drv changes, but will it do the right thing in that case?
Good question.
The implementation in the patch creates a single Cocoa window for all full-screen DCs. So the rendering from all contexts would go to the same drawable. Currently, there's also a single pixel format tracked, although it always allows the pixel format to be changed even if it was already set. That's almost certainly wrong. I was planning to change that to track the pixel format per DC in which case I'd probably enforce the usual rules about changing it. I'm not sure that's right, either. Does it make sense for multiple callers to create separate DCs with separate pixel formats but sharing a drawable?
wglGetFullscreenDCWINE() might be a more appropriate name for how we're using this.
The implication being that there should be one full-screen DC and all callers would share it? Maybe that's OK. I'm not sure. It has the issue with the pixel format – over its lifetime, can a shared DC have different pixel formats at different times? (Leaving aside the question of whether different callers would want to set different pixel formats simultaneously.)
Here's another approach to that same question. What if the WGL_WINE_fullscreen_dc extension didn't add any new functions? What if it simply indicated that doing OpenGL on the screen DC returned by GetDC(0) was allowed and full-featured? Then, the change to wined3d would be to simply use GetDC(0) for a full-screen swapchain. Releasing the DC could go through ReleaseDC() (and maybe wined3d_release_dc() with some tweaking).
The implementation in the driver would detect the screen DC using WindowFromDC(hdc) == GetDesktopWindow() much like what I did in attachment 46977 (which isn't that different from the newer patch). In other words, the driver-side behavior would be just the same, just with a different means of detecting when a DC was full-screen.
Would that work? What about the issue with the pixel format? Are there other issues?