From: Dimitar K. <dko...@gm...> - 2009-09-07 14:04:56
|
Hello, I sent this to mesa3d-dev, which was probably not the right place. 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). 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? -- Dimitar Kodjabachev |
From: Brian P. <br...@vm...> - 2009-09-08 15:18:08
|
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(). I don't think I can help with this memory leak. Maybe someone else who works on Windows can help you. -Brian |
From: Karl S. <kar...@gm...> - 2009-09-08 16:20:22
|
On Tue, Sep 8, 2009 at 9:17 AM, Brian Paul <br...@vm...> 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 -Brian > > > ------------------------------------------------------------------------------ > 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 > Mes...@li... > https://lists.sourceforge.net/lists/listinfo/mesa3d-users > |
From: Karl S. <kar...@gm...> - 2009-09-08 17:31:38
|
On Tue, Sep 8, 2009 at 11:19 AM, José Fonseca <jfo...@vm...> wrote: > On Tue, 2009-09-08 at 09:20 -0700, Karl Schultz wrote: > > > > > > On Tue, Sep 8, 2009 at 9:17 AM, Brian Paul <br...@vm...> 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 > > |