On 29 January 2014 01:47, Ken Thomases ken@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 care enough.
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.