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.

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

Reply via email to