> > Roderick Colenbrander wrote : > > >> Roderick Colenbrander wrote : > > >> > > >>> 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; > > >> Thanks to your hints I could make the attached patch. It fixes the > > issue > > >> on my > > >> side : wglGetPbufferDCARB returns a DC which type is OBJ_DC and WoW > > does > > >> not > > >> flicker any more. > > >> > > >> Regards, > > >> > > >> Bertrand. > > > > > > @@ -1869,16 +1869,18 @@ static HDC WINAPI X11DRV_wglGetPbufferDC > > > { > > > Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; > > > HDC hDC; > > > + int iPixelFormat; > > > + PIXELFORMATDESCRIPTOR pfd; > > > if (NULL == object) { > > > SetLastError(ERROR_INVALID_HANDLE); > > > return NULL; > > > } > > > - hDC = CreateCompatibleDC(object->hdc); > > > > > > - /* The function wglGetPbufferDCARB returns a DC to which the > > pbuffer can be connected. > > > - * We only support one onscreen rendering format (the one from > the > > main visual), so use that. */ > > > - SetPixelFormat(hDC, 1, NULL); > > > - set_drawable(hDC, object->drawable); /* works ?? */ > > > + hDC = CreateDCA("DISPLAY", NULL, NULL, NULL); > > > + iPixelFormat = GetPixelFormat(object->hdc); > > > + DescribePixelFormat(hDC, iPixelFormat, > > sizeof(PIXELFORMATDESCRIPTOR), &pfd); > > > + SetPixelFormat(hDC, iPixelFormat, &pfd); > > > + > > > TRACE("(%p)->(%p)\n", hPbuffer, hDC); > > > return hDC; > > > } > > > > > > I'm not sure if this is correct for all programs. Some more testing > > needs to be done in other programs that use pbuffers. The set_drawable > line > > must have a purpose (though I like to get rid of it or atleast implement > it > > without ExtEscape). And I'm also not sure if we need to retrieve the > > pixelformat of the 'parent hdc' as it is allways 1 though retrieving it > is nicer. > > > > > > Roderick > > > > The patch fixes the bug whether the set_drawable is included or not. So > I > > guess > > it does not hurt. I also dug in the wine-patches mailing list and it > > appeared > > that you included this line in your original patch (see > > http://www.winehq.org/pipermail/wine-patches/2006-September/030335.html) > > but > > infortunately you did not give any detail at the time about the reason > of > > its > > inclusion. Yet it seems logical that the DC returned by > wglGetPbufferDCARB > > is > > linked to the Pbuffer drawable rather than the window drawable. > > > > About the retrival of the pixel format of the 'parent hdc', I agree that > > it is a > > bit overkill but once again it does not hurt and it may prevent bugs to > > occur if > > one day Wine will use more than one pixel format. > > > > So what about this patch ? > > > > @@ -1869,16 +1869,18 @@ static HDC WINAPI X11DRV_wglGetPbufferDC > > { > > Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; > > HDC hDC; > > + int iPixelFormat; > > + PIXELFORMATDESCRIPTOR pfd; > > if (NULL == object) { > > SetLastError(ERROR_INVALID_HANDLE); > > return NULL; > > } > > - hDC = CreateCompatibleDC(object->hdc); > > > > - /* The function wglGetPbufferDCARB returns a DC to which the > pbuffer > > can be > > connected. > > - * We only support one onscreen rendering format (the one from the > > main > > visual), so use that. */ > > - SetPixelFormat(hDC, 1, NULL); > > + hDC = CreateDCA("DISPLAY", NULL, NULL, NULL); > > + iPixelFormat = GetPixelFormat(object->hdc); > > + DescribePixelFormat(hDC, iPixelFormat, > sizeof(PIXELFORMATDESCRIPTOR), > > &pfd); > > + SetPixelFormat(hDC, iPixelFormat, &pfd); > > set_drawable(hDC, object->drawable); /* works ?? */ > > + > > TRACE("(%p)->(%p)\n", hPbuffer, hDC); > > return hDC; > > } > > > > About testing, I don't have an app other than WoW that uses OpenGL (not > to > > mention Pbuffers) so if some people out there could give this patch a > > try... > > > > Bertrand. > > The main issue I still have with the patch which isn't something you have > done wrong is set_drawable. Before I started moving the original opengl32 > code to winex11.drv (I didn't write the WGL code), there was a need to get > access to X11 data inside opengl32. For this purpose 'ExtEscape' got used. > This isn't a nice mechanism and Alexandre wants to get rid of it as much as > possible. > > The set_drawable call uses ExtEscape too. I think I'm going to move a part > of wglGetCurrentDCARB to gdi32.dll in which we can do CreateDCA. Then we > can pass the HDC and pbuffer to the other part of wglGetCurrentDCARB which > will be in winex11.drv. The winex11.drv version can then just set the > drawable in a X11DRV_PDEVICE (x11drv version of a hdc). > > Regards, > Roderick
Could you check if the attached patch works? It does more or less what I explained in the last email. If it works I'll clean it up as right now it is a bit hacky. I hope to find some apps to test it on. Regards, Roderick -- GMX DSL-Flatrate 0,- Euro* - Überall, wo DSL verfügbar ist! NEU: Jetzt bis zu 16.000 kBit/s! http://www.gmx.net/de/go/dsl
Index: dlls/gdi32/driver.c =================================================================== RCS file: /home/wine/wine/dlls/gdi32/driver.c,v retrieving revision 1.3 diff -u -r1.3 driver.c --- dlls/gdi32/driver.c 31 Oct 2006 21:11:10 -0000 1.3 +++ dlls/gdi32/driver.c 4 Nov 2006 16:57:04 -0000 @@ -199,6 +199,7 @@ GET_FUNC(wglCreateContext); GET_FUNC(wglDeleteContext); GET_FUNC(wglGetProcAddress); + GET_FUNC(wglGetPbufferDCARB); GET_FUNC(wglMakeContextCurrentARB); GET_FUNC(wglMakeCurrent); GET_FUNC(wglShareLists); Index: dlls/gdi32/gdi_private.h =================================================================== RCS file: /home/wine/wine/dlls/gdi32/gdi_private.h,v retrieving revision 1.3 diff -u -r1.3 gdi_private.h --- dlls/gdi32/gdi_private.h 31 Oct 2006 21:11:10 -0000 1.3 +++ dlls/gdi32/gdi_private.h 4 Nov 2006 16:57:05 -0000 @@ -187,6 +187,7 @@ HGLRC (*pwglCreateContext)(PHYSDEV); BOOL (*pwglDeleteContext)(HGLRC); PROC (*pwglGetProcAddress)(LPCSTR); + HDC (*pwglGetPbufferDCARB)(PHYSDEV, void*); BOOL (*pwglMakeCurrent)(PHYSDEV, HGLRC); BOOL (*pwglMakeContextCurrentARB)(PHYSDEV, PHYSDEV, HGLRC); BOOL (*pwglShareLists)(HGLRC hglrc1, HGLRC hglrc2); Index: dlls/gdi32/opengl.c =================================================================== RCS file: /home/wine/wine/dlls/gdi32/opengl.c,v retrieving revision 1.3 diff -u -r1.3 opengl.c --- dlls/gdi32/opengl.c 31 Oct 2006 21:11:10 -0000 1.3 +++ dlls/gdi32/opengl.c 4 Nov 2006 16:57:05 -0000 @@ -130,6 +130,19 @@ return ctx->hdc; } +static WINAPI HDC wglGetPbufferDCARB(void *pbuffer) +{ + DC * dc = NULL; + HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); + HDC ret; + + dc = DC_GetDCPtr(hdc); + ret = dc->funcs->pwglGetPbufferDCARB(dc->physDev, pbuffer); + + GDI_ReleaseObj(hdc); + return ret; +} + /*********************************************************************** * wglMakeCurrent (OPENGL32.@) */ @@ -281,6 +294,8 @@ */ if(ret && strcmp(func, "wglMakeContextCurrentARB") == 0) return wglMakeContextCurrentARB; + else if(ret && strcmp(func, "wglGetPbufferDCARB") == 0) + return wglGetPbufferDCARB; return ret; } Index: dlls/winex11.drv/opengl.c =================================================================== RCS file: /home/wine/wine/dlls/winex11.drv/opengl.c,v retrieving revision 1.31 diff -u -r1.31 opengl.c --- dlls/winex11.drv/opengl.c 3 Nov 2006 13:33:49 -0000 1.31 +++ dlls/winex11.drv/opengl.c 4 Nov 2006 16:57:26 -0000 @@ -1865,22 +1865,19 @@ } /* WGL_ARB_pbuffer: wglGetPbufferDCARB */ -static HDC WINAPI X11DRV_wglGetPbufferDCARB(HPBUFFERARB hPbuffer) +HDC WINAPI X11DRV_wglGetPbufferDCARB(X11DRV_PDEVICE *physDev, HPBUFFERARB hPbuffer) { Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer; - HDC hDC; if (NULL == object) { SetLastError(ERROR_INVALID_HANDLE); return NULL; } - hDC = CreateCompatibleDC(object->hdc); - /* The function wglGetPbufferDCARB returns a DC to which the pbuffer can be connected. - * We only support one onscreen rendering format (the one from the main visual), so use that. */ - SetPixelFormat(hDC, 1, NULL); - set_drawable(hDC, object->drawable); /* works ?? */ - TRACE("(%p)->(%p)\n", hPbuffer, hDC); - return hDC; + physDev->current_pf = 1; + physDev->drawable = object->drawable; + + TRACE("(%p)->(%p)\n", hPbuffer, physDev->hdc); + return physDev->hdc; } /* WGL_ARB_pbuffer: wglQueryPbufferARB */ @@ -2377,7 +2374,7 @@ GLint prev_binded_tex; pglGetIntegerv(object->texture_target, &prev_binded_tex); if (NULL == object->render_ctx) { - object->render_hdc = X11DRV_wglGetPbufferDCARB(hPbuffer); +// object->render_hdc = X11DRV_wglGetPbufferDCARB(hPbuffer); /* FIXME: This is routed through gdi32.dll to winex11.drv, replace this with GLX calls */ object->render_ctx = wglCreateContext(object->render_hdc); do_init = 1; @@ -2827,6 +2824,12 @@ return NULL; } +HDC WINAPI X11DRV_wglGetPbufferDCARB(X11DRV_PDEVICE *hDevice, HPBUFFERARB hPbuffer) +{ + ERR_(opengl)("No OpenGL support compiled in.\n"); + return NULL; +} + BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* hDrawDev, X11DRV_PDEVICE* hReadDev, HGLRC hglrc) { ERR_(opengl)("No OpenGL support compiled in.\n"); return FALSE; Index: dlls/winex11.drv/winex11.drv.spec =================================================================== RCS file: /home/wine/wine/dlls/winex11.drv/winex11.drv.spec,v retrieving revision 1.13 diff -u -r1.13 winex11.drv.spec --- dlls/winex11.drv/winex11.drv.spec 31 Oct 2006 21:11:11 -0000 1.13 +++ dlls/winex11.drv/winex11.drv.spec 4 Nov 2006 16:57:26 -0000 @@ -134,6 +134,7 @@ @ cdecl wglCreateContext(ptr) X11DRV_wglCreateContext @ cdecl wglDeleteContext(long) X11DRV_wglDeleteContext @ cdecl wglGetProcAddress(str) X11DRV_wglGetProcAddress +@ cdecl wglGetPbufferDCARB(ptr ptr) X11DRV_wglGetPbufferDCARB @ cdecl wglMakeContextCurrentARB(ptr ptr long) X11DRV_wglMakeContextCurrentARB @ cdecl wglMakeCurrent(ptr long) X11DRV_wglMakeCurrent @ cdecl wglShareLists(long long) X11DRV_wglShareLists