> > 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