On Wed, Sep 9, 2009 at 10:03 AM, Dimitar Kodjabachev <dkodjabac...@gmail.com
> wrote:

> On Tue, Sep 8, 2009 at 8:31 PM, Karl Schultz<karl.w.schu...@gmail.com>
> wrote:
> >
> >
> > On Tue, Sep 8, 2009 at 11:19 AM, José Fonseca <jfons...@vmware.com>
> wrote:
> >>
> >> On Tue, 2009-09-08 at 09:20 -0700, Karl Schultz wrote:
> >> >
> >> >
> >> > On Tue, Sep 8, 2009 at 9:17 AM, Brian Paul <bri...@vmware.com> wrote:
> >> >         Dimitar Kodjabachev wrote:
> >> >         > Hello,
> >> >         >
> >> >         > I sent this to mesa3d-dev, which was probably not the right
> >> >         place.
> >> >
> >> >
> >> >         mesa3d-dev is OK since there may be a bug in the Mesa wgl
> >> >         code.  I'm
> >> >         cc'ing mesa3d-dev.
> >> >
> >> >
> >> >         > I have the following situation (pseudocode) with Mesa 7.4.4:
> >> >         >
> >> >         > hglrc1 = wglCreateContext(hdc1)
> >> >         > wglMakeCurrent(hdc1,hglrc1)
> >> >         > hglrc2 = wglCreateContext(hdc2)
> >> >         > wglMakeCurrent(hdc2,hglrc2)
> >> >         > wglMakeCurrent(hdc3,hglrc2)
> >> >         > wglDeleteContext(hglrc1)
> >> >         > wglDeleteContext(hglrc2)
> >> >         >
> >> >         > As a result of this sequence of calls, a WMesaFramebuffer
> >> >         structure is leaked.
> >> >         > The call causing the leak is wglMakeCurrent(hdc3,hglrc2).
> >> >         This is what I know
> >> >         > so far:
> >> >         >
> >> >         > -> wglMakeCurrent(hdc3,hglrc2) calls
> >> >         >  -> WMesaMakeCurrent(hglrc2,hdc3) which calls
> >> >         >  -> wmesa_lookup_framebuffer(hdc3) which returns NULL, as
> >> >         the hdc given to
> >> >         >      wglMakeCurrent is different from the one given at the
> >> >         time
> >> >         >      of wglCreateContext
> >> >         >  -> wmesa_new_framebuffer() is called and a new frame buffer
> >> >         is allocated
> >> >         >
> >> >         > This new frame buffer is not released upon
> >> >         wglDeleteContext(hglrc2).
> >> >
> >> >
> >> >         A rendering context is not the same as a drawing surface.  So
> >> >         deleting
> >> >         a rendering context does not imply deleting a surface.
> >> >
> >> >
> >> >         > As far as
> >> >         > I know, the device context passed to wglMakeCurrent does not
> >> >         have to
> >> >         > be the same as the one passed to wglCreateContext as long as
> >> >         the the actual
> >> >         > device and the pixel formats are.  Is this correct or is my
> >> >         usage wrong?
> >> >
> >> >
> >> >         My understanding is that the context passed to
> >> >         wglMakeCurrent() must
> >> >         have been created by a call to wglCreateContext().
> >> >
> >> >
> >> > Right, but there are two contexts passed in wglMakeCurrent().  Here
> >> > the GL context (rendering context) is hglrc2, created by
> >> > wglCreateContext().  But the Window context (device context) is hdc3,
> >> > which is just a Windows Win32 handle.
> >> >
> >> >
> >> >         I don't think I can help with this memory leak.  Maybe someone
> >> >         else
> >> >         who works on Windows can help you.
> >> >
> >> >
> >> > The problem is that wglMakeCurrent() will lazily allocate the
> >> > framebuffer when a device context is made current for the first time.
> >> > The created framebuffer gets added onto a list and is tagged with the
> >> > device context that it was just associated with.  When a rendering
> >> > context is destroyed, this list is searched for a framebuffer tagged
> >> > with the device context that is current at the time the rendering
> >> > context was destroyed, and if found, the framebuffer is freed.
> >> >
> >> > Note that this conflicts with what Brian said above about deleting
> >> > surfaces.  I imagine that this was added to wgl as a way to free the
> >> > framebuffer *somehow*.
> >> >
> >> > The leak is caused here because the rendering context is associated
> >> > with two device contexts.  A framebuffer is created for each device.
> >> > Later, when the rendering context is destroyed, only one framebuffer
> >> > is freed, because only one device context can be current when
> >> > destroying the rendering context, and only the framebuffer tagged with
> >> > that device context is freed.
> >> >
> >> > Since destroying a rendering context shouldn't destroy any surfaces,
> >> > it isn't an option to tag all framebuffers with the rendering context
> >> > id and then delete all framebuffers tagged that way when a rendering
> >> > context is destroyed.  Although this would fix the leak.
> >> >
> >> > The right way, I think, is to destroy the framebuffer associated with
> >> > a device context when the device context is destroyed.  This might
> >> > involve hooking Windows somehow to get a notification when it is
> >> > destroyed or setting up a message handler to get WM_DESTROY messages
> >> > so that we can free resources associated with the device.
> >> >
> >> > The wgl code hasn't been all that robust or complete, and I don't know
> >> > right now if this design/approach is even correct.  I'd have to dig
> >> > into this more.
> >> >
> >> > Right now, I don't have much of a workaround to suggest for the
> >> > current implementation except to try to destroy hglrc2 and recreate it
> >> > before making current with hdc3.
> >> >
> >> >
> >> > Karl
> >>
> >> What WGL implementation are we talking about here? One of the pure Mesa
> >> based one in src/mesa/drivers/windows/gdi, or the Gallium based one in
> >> src/gallium/state_trackers/wgl ?
> >>
> >
> > I was talking about the former - the pure Mesa one.  I think that the OP
> was
> > talking about the same.
> >
> >>
> >> The Gallium WGL state tracker is a faily complete implementation of both
> >> WGL and ICD interfaces and at least the ICD interface has received a lot
> >> of testing. The drawback is that the only available driver for it ATM is
> >> softpipe, which is in generally slower than Mesa's swrast.
> >>
> >
> > Yes, that implementation of wgl is much better.  It does have a
> windowproc
> > to handle resize and destroy events, which frees the framebuffer
> resources
> > as I had suggested.
> >
> >>
> >> Jose
> >>
> >
> >
> >
> ------------------------------------------------------------------------------
> > Let Crystal Reports handle the reporting - Free Crystal Reports 2008
> 30-Day
> > trial. Simplify your report design, integration and deployment - and
> focus
> > on
> > what you do best, core application coding. Discover what's new with
> > Crystal Reports now.  http://p.sf.net/sfu/bobj-july
> > _______________________________________________
> > Mesa3d-users mailing list
> > mesa3d-us...@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/mesa3d-users
> >
> >
>
> Why not reuse a frame buffer once it is created?  I may not understand the
> ideology of the structures, but what I have done to patch the leak is to
> tag
> each frame buffer with the rendering context for which it was initially
> created
> (along with the *current* device context).  This way wglMakeCurrent() will
> create only one frame buffer for each rendering context and (re)use it
> until
> wglDeleteContext() is called.
>
>
That might plug the leak and might work if your application changed contexts
only between complete frames, like after the call to eglSwapBuffers.  But
the semantics are that the framebuffer is associated with the device
(window) and not the rendering context.

Brian even pointed out in this thread that deleting the rendering context
should not involve the deletion of framebuffers.  That is why the other wgl
code destroys framebuffers in the WM_DESTROY processing in the winproc.
This wgl code is just plain wrong.

If you keep (resuse, in your words) the framebuffer with the rendering
context, then any partial-frame rendering you do to one device (window) will
be carried over to another device if you call make current with the same
rendering context and a new device.  In some way, you'll have unwanted
behavior in terms of frame buffer content.  But like I said, it may just
happen to work ok with certain restrictions such as drawing and swapping
only complete frames..

The right fix is to add the code to delete the framebuffers via a winproc,
or better, port the wgl code from the tracker side of the tree back here.  I
don't know how important it would be to do this.

Karl

--
> Dimitar Kodjabachev
>
>
> ------------------------------------------------------------------------------
> Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
> trial. Simplify your report design, integration and deployment - and focus
> on
> what you do best, core application coding. Discover what's new with
> Crystal Reports now.  http://p.sf.net/sfu/bobj-july
> _______________________________________________
> Mesa3d-dev mailing list
> Mesa3d-dev@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mesa3d-dev
>
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to