Roderick Colenbrander wrote :
Hi,
After investigating a bit in the Wine code, it seems that the
flickering
bug of WoW in OpenGL mode is due to wglGetPbufferDCARB that returns a
DC
which type is OBJ_MEMDC while it should return a DC which type is OBJ_DC. And since in the current git tree, the DC type of a Pbuffer
is
OBJ_MEMDC then the code located in lines 1394-1395 of dlls/winex11.drv/opengl.c is executed : the Pbuffer is copied to the screen each time the GL context is made current to the Pbuffer hence
the
flickering (WoW bounds the GL context alternatively to the screen and
to
the Pbuffer). The expected behaviour is not to copy the Pbuffer
content
to the screen since WoW does it itself.
The easiest workaround for this bug would be to make X11DRV_wglGetPbufferDCARB to return the Pbuffer's object->hdc (this fixes the flickering bug). However, I have made some tests with
Windows
XP and it appears that wglGetPbufferDCARB returns a HDC different
from
the HDC passed when wglCreatePbufferARB was called. So such a patch would be a dirty hack not a real fix.
I am not familiar enough with Wine to submit a patch so I leave the gurus out there find an elegant solution.
Attached is the code that I used to perform a few tests about
Pbuffers
on Windows XP (code of interest is located from line 293 to line
298).
Regards,
Bertrand.
It is correct that the return of OBJ_MEMDC causes the flickering as it
turns on the line glDrawBuffer. One of the reasons I started to rewrite opengl32 was because of this. Right now most code is inside winex11.drv
in
which we have much more control over things.
The easiest hack I thought about some months ago is to just set a flag
in the device returned wglGetPbufferDCARB though it would be tricky to
get a
X11DRV_PDEVICE in a 'legal' (AJ-proof) way.
There's also a chance that a hack like this isn't needed at all.
Originally Huw Davies added the glDrawBuffer code together with
X11DRV_SYNC_PIXMAP
code to winex11.drv/opengl32 in order to allow windowed opengl rendering using DIBs. The glDrawBuffer line was used for emulating single
buffering.
Recently Ulrich Czekalla worked on a better fix for the windowed
opengl
problem using glScissors. For this patch various calls like glViewport, glScissor and others need to be patched. It might be possible to get rid
of
the glDrawBuffer / x11 pixmap rendering code but Huw would need to
answer
that as he knows for what it was needed and it fully works.
I really hope it can be removed when the scissors code is in, it would
simplify the code and make my work easier.
Regards, Roderick
OK such a patch would remove the flickering bug for WoW but what about
the
wrong type of the Pbuffer's DC ? Obviously, Windows XP attaches a DC which
type
is OBJ_DC to the Pbuffers. I don't know if some apps rely on the assumption that GetObjectType(wglGetPbufferDCARB(...)) == OBJ_DC, but if some do they might behave wrongly with Wine.
Regards,
Bertrand.
I didn't have time yet to reply to the other email. This should be investigated more thoroughly. Second as this would be a 'serious' bug in Wine we need to convince Alexandre that this behavior is correct. For this purpose we need a test case. If you check the wine source you'll see that most dlls contain test cases using certain APIs. These testcases are used on wine and different windows versions to test the behavior of a function. Since the behavior of GetObjectType for this case is badly documented it should be added. Most likely it should be added to gdi32 and then dynamicly load opengl32.dll (you likely need to provide the function prototypes yourself if they aren't in wingdi.h as we don't have wine opengl headers yet).
If you could write such a test case in order to convince AJ that would be very usefull.
Regards, Roderick
Or perhaps a testcase isn't needed at all. I think the use of CreateCompatibleDC in wglGetPbufferDCARB is incorrect. According to MSDN this function creates a memory device context. Perhaps something like this works: HDC hdc = CreateDC(...); int format_orig = GetPixelFormat(hdc_orig); SetPixelFormat(hdc, format_orig); return hdc;