Fixing conflicts between WineD3D and WGL
hverbeet at gmail.com
Wed Jan 29 05:10:12 CST 2014
On 29 January 2014 01:47, Ken Thomases <ken at codeweavers.com> wrote:
> The most important things to achieve are a) to not "consume" the only opportunity the app has to set the window's pixel format, and b) to restore the app's current GL context (and implicitly its DC) when returning control to it. I don't think it's necessary to avoid WineD3D ever changing WGL's notion of the current context. Certainly, while a WineD3D GL context is current, GL functions like glClear() will operate on WineD3D's context. If the app thinks its context is current and calls GL functions, its context better really be current. So, WineD3D really needs to restore the app's context before returning control (and it generally does, I think). If it's going to do that, then wglGetCurrentContext() will take care of itself. Same for wglGetCurrentDC().
There may be performance reasons though. The wglMakeCurrent() required
to restore the previous GL context is pretty expensive, so
applications that have a GL context current while calling into wined3d
take a considerable performance hit. I think I've only ever seen 1 or
2 applications that were affected that though, so perhaps we don't
> There's a wrinkle having to do with the pixel format. User32 and the wineserver use the fact that a window has a pixel format to compute the "surface region" for the top-level window. This is a different "surface" than the concept central to this proposal. This "surface" is used for client-side GDI rendering using the DIB engine. Maintaining a surface region is necessary to prevent the contents of the window surface buffer from being blitted on top of any 3D rendering done to the window. To keep that functioning, the graphics drivers will still have to inform user32 that 3D rendering is being done to the window. It can do that using the existing mechanism, but that's not currently reversible because it's tied to the pixel format and that's a permanent property of a window. We'd like it to be reversible, since WineD3D can stop targeting a window. I'm thinking of using a count in user32.
Potentially related, http://bugs.winehq.org/show_bug.cgi?id=15232. I'm
not entirely sure on all the details around WS_CLIPCHILDREN,
particularly in fullscreen mode, but it's probably something else to
keep in mind.
> Extension WGL_WINE_make_current:
> BOOL wglMakeContextCurrentWINE(HGLRC hglrc);
> The standard WGL function wglMakeCurrent() combines two operations. It sets the a GL context's drawable to the provided DC and it makes the GL context current for the thread. This new function, wglMakeContextCurrentWINE(), would only do the latter. It would make a GL context current for the thread without changing which DC it's associated with. Both the X11 and Mac drivers already maintain the necessary state to do that. They don't need to have the DC passed in again. (If a GL context is associated with separate draw and read DCs using wglMakeContextCurrentARB(), then this function will leave it associated with both DCs.)
> This allows WineD3D to faithfully restore the app's previously-current WGL context. This addresses bug 28869.
Maybe. Note that some of the quirk detection code renders to this
context. I think all rendering there goes to FBOs, so in that regard
it's probably safe, but it does feel a bit fragile. For regular
wined3d rendering we do of course need a drawable, although this may
work out in practice.
> What do folks think? Any feedback would be appreciated.
I think WGL_WINE_surface would work from wined3d's point of view, at
the very least interface wise. There are probably some details to work
out about how it should interact with gdi32 rendering and things like
the window moves, minimization, etc. I don't have as good of an
overview of how it would work out for winex11. I'm not so sure about
WGL_WINE_make_current, but it may be enough in practice.
More information about the wine-devel