Flickering bug for World of Warcraft
bcoconni at club-internet.fr
Sat Nov 4 03:49:26 CST 2006
Jesse Allen wrote :
> On 11/3/06, Bertrand Coconnier <bcoconni at club-internet.fr> wrote:
>> 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.
> "To create a device context for the pbuffer, call
> HDC wglGetPbufferDCARB(HPBUFFERARB hPbuffer);
> where <hPbuffer> is a handle returned from a previous call to
> wglCreatePbufferARB. A device context is returned by
> wglGetPbufferDCARB which can be used to associate a rendering
> context with the pbuffer. Any rendering context created with
> a wglCreateContext that is "compatible" with the <iPixelFormat> may
> be used to render into the pbuffer."
> So yes, it's supposed to return a new one.
> So I can understand better, what are these set to when you run your
> program on both windows and linux?
> type1 = GetObjectType(hDC);
> type2 = GetObjectType(pBufferHDC);
Under Windows XP : type1 == OBJ_DC
type2 == OBJ_DC
Under Wine : type1 == OBJ_DC
type2 == OBJ_MEMDC /* should be OBJ_DC since pBuffers are supposed to be
located in Video Memory or whatever its name */
And since device contexts of Wine's pBuffers are OBJ_MEMDC, the following code
in X11DRV_wglMakeCurrent is executed (line 1392 of dlls/winex11.drv/opengl.c) :
if(ret && type == OBJ_MEMDC)
ctx->do_escape = TRUE;
the content of the Pbuffer's DC is copied to the color buffer by Wine while it
should not (there is no reason for some memory data to be copied to the color
buffer when a GL context is made current to a Pbuffer).
More information about the wine-devel