[vtkusers] C++ example (was Re: X Error of failed request: GLXBadDrawable)
Mathieu Malaterre
mathieu.malaterre at gmail.com
Mon Jun 30 07:44:17 EDT 2008
Ok, if anyone is interested in the problem. Here is a very easy way to
reproduce it (*). At least on my X11-debian box it crash at index=450.
So in summary:
1. vtkRenderWindow::Finalize is indeed doing what it claims
2. if a vtkRenderWindowInteractor is associated with the
vtkRenderWindow, then the finalize is -somehow- not working anymore
(*)
#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
int main()
{
vtkSphereSource *sphere = vtkSphereSource::New();
vtkPolyDataMapper *sphereMapper = vtkPolyDataMapper::New();
sphereMapper->SetInput(sphere->GetOutput());
vtkActor* sphereActor = vtkActor::New();
sphereActor->SetMapper(sphereMapper);
vtkRenderer *ren = vtkRenderer::New();
ren->AddActor(sphereActor);
// Create a dummy rwi that will serve as reference DisplayId
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren);
iren->SetRenderWindow(renWin);
iren->Initialize();
iren->Start();
// at this point the user is supposed to 'q' quit the mainloop
const int nrenwin = 1000;
vtkRenderWindowInteractor * list[nrenwin];
vtkRenderWindow * list1[nrenwin];
for(int i = 0; i < nrenwin; ++i)
{
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
vtkRenderWindow *renWin1 = vtkRenderWindow::New();
// Work-around for Max Xlib:
renWin1->SetDisplayId( renWin->GetGenericDisplayId() );
//iren->SetRenderWindow( renWin1 ); // If uncomment it stops working
list[i] = iren;
list1[i] = renWin1;
renWin1->AddRenderer(ren);
renWin1->Render();
renWin1->Finalize();
std::cout << i << std::endl;
}
// All vtk-pointers are still in memory, but we passed the opengl
hardcoded limit :)
for(int i = 0; i < nrenwin; ++i)
{
list[i]->Delete();
list1[i]->Delete();
}
iren->Delete();
renWin->Delete();
ren->Delete();
sphereActor->Delete();
sphereMapper->Delete();
sphere->Delete();
return 0;
}
On Fri, Jun 27, 2008 at 4:24 PM, Mathieu Malaterre
<mathieu.malaterre at gmail.com> wrote:
> Hum... I have reduced the sample even more (using only VTK class) and
> I cannot reproduce the bug I am seeing from python+wx:
>
> #include "vtkSphereSource.h"
> #include "vtkPolyDataMapper.h"
> #include "vtkActor.h"
> #include "vtkRenderer.h"
> #include "vtkRenderWindow.h"
> #include "vtkRenderWindowInteractor.h"
>
> int main()
> {
> vtkSphereSource *sphere = vtkSphereSource::New();
> vtkPolyDataMapper *sphereMapper = vtkPolyDataMapper::New();
> sphereMapper->SetInput(sphere->GetOutput());
>
> vtkActor* sphereActor = vtkActor::New();
> sphereActor->SetMapper(sphereMapper);
>
> vtkRenderer *ren = vtkRenderer::New();
> ren->AddActor(sphereActor);
>
> vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
> vtkRenderWindow *renWin = vtkRenderWindow::New();
> renWin->AddRenderer(ren);
> iren->SetRenderWindow(renWin);
> iren->Initialize();
> iren->Start();
>
> const int nrenwin = 500;
> vtkRenderWindow * list[nrenwin];
> for(int i = 0; i < nrenwin; ++i)
> {
> vtkRenderWindow *renWin1 = vtkRenderWindow::New();
> list[i] = renWin1;
> // Work-around for Max Xlib:
> renWin1->SetDisplayId( renWin->GetGenericDisplayId() );
> renWin1->AddRenderer(ren);
> renWin1->Render();
> renWin1->Finalize();
> std::cout << i << std::endl;
> }
> for(int i = 0; i < nrenwin; ++i)
> {
> list[i]->Delete();
> }
>
> iren->Delete();
> renWin->Delete();
> ren->Delete();
> sphereActor->Delete();
> sphereMapper->Delete();
> sphere->Delete();
>
> return 0;
> }
>
> On Fri, Jun 27, 2008 at 3:45 PM, Mathieu Malaterre
> <mathieu.malaterre at gmail.com> wrote:
>> Here is a short wx example to demonstrate the issue:
>>
>> 1. You can hit the X limit pretty easily replacing
>> wxVTKRenderWindowInteractor with wxVTKRenderWindow (in which case each
>> renderwindow will creates its own X Display)
>>
>> 2. The issue I can still not work around can be reproduced using the
>> following python-wx script (*). Even using the complicated (ref Charl
>> Boath) finalization scheme it seems that something is not getting
>> clean up here. Could an opengl guru recommend a way to track down the
>> opengl call that might be leaked ?
>>
>>
>> Basically all I am doing is create enough widget on the first notebook
>> page, so that when user click on page 2:
>> -> I get rid of all widget from page 1
>> -> all widget defined on page 2 are getting created until we hit the
>> hardcoded limit
>>
>> Thanks !
>> -Mathieu
>> Ps: you might have to tweak grid=(15,15) for your particular opengl driver
>>
>> (*)
>> import wx
>>
>> from vtk import *
>> # important to use wxVTKRenderWindowInteractor here since it implement
>> the wx.GetXDisplay() trick
>> from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
>>
>>
>> class Page(wx.Panel):
>> def __init__(self, parent):
>> wx.Panel.__init__(self, parent)
>> grid=(15,15)
>> sizer = wx.GridSizer(rows=grid[0], cols=grid[1], hgap=1, vgap=1)
>> n = grid[0]*grid[1]
>>
>> sphere = vtkSphereSource()
>> sphereMapper = vtkPolyDataMapper()
>> sphereMapper.SetInput(sphere.GetOutput())
>>
>> sphereActor = vtkActor()
>> sphereActor.SetMapper(sphereMapper)
>>
>> self._wlist=[]
>> for i in range(0,n):
>> ren = vtkRenderer()
>> ren.AddActor(sphereActor)
>> renWin = wxVTKRenderWindowInteractor(self,-1, size=(10,10))
>> self._wlist.append( renWin )
>> renWin.GetRenderWindow().AddRenderer(ren)
>> sizer.Add( renWin, 1, wx.EXPAND)
>>
>> self.SetSizer(sizer)
>>
>> class MainFrame(wx.Frame):
>> def __init__(self):
>> wx.Frame.__init__(self, None, title="Simple Notebook Example")
>>
>> p = wx.Panel(self)
>> nb = wx.Notebook(p)
>> nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.MyPageChanged,id=nb.GetId())
>>
>> self._page1 = Page(nb)
>> self._page2 = Page(nb)
>>
>> nb.AddPage(self._page1, "Page 1")
>> nb.AddPage(self._page2, "Page 2")
>>
>> sizer = wx.BoxSizer()
>> sizer.Add(nb, 1, wx.EXPAND)
>> p.SetSizer(sizer)
>>
>> def MyPageChanged(self,event=None):
>> # We should first Finalize the old ones:
>> print event.GetOldSelection()
>> if event.GetOldSelection() == 0:
>> for w in self._page1._wlist:
>> renderers = w.GetRenderWindow().GetRenderers()
>> numRenderers = renderers.GetNumberOfItems()
>> renderers.InitTraversal()
>> for i in range(0,numRenderers):
>> w.GetRenderWindow().RemoveRenderer(renderers.GetNextItem())
>> w.GetRenderWindow().Finalize()
>> w.SetRenderWindow(None)
>> del w
>>
>> event.Skip()
>>
>> if __name__ == "__main__":
>> app = wx.App()
>> MainFrame().Show()
>> app.MainLoop()
>>
>>
>> On Thu, Jun 26, 2008 at 4:55 PM, Mathieu Malaterre
>> <mathieu.malaterre at gmail.com> wrote:
>>> Hello there,
>>>
>>> I am currently stuck on the following problem: when creating a lot
>>> of vtkRenderWindow (vtkXOpenGLRenderWindow in my case), there are two
>>> issues:
>>>
>>> 1. X has a limited number of Display. And you get an error like that:
>>>
>>> ...
>>> Xlib: connection to ":0.0" refused by server
>>> Xlib: Maximum number of clients reached
>>> ERROR: In /home/mmalaterre/Projects/VTK52/Rendering/vtkXOpenGLRenderWindow.cxx,
>>> line 1592
>>> vtkXOpenGLRenderWindow (0x2494140): bad X server connection. DISPLAY=:0
>>> ...
>>>
>>> This can easily be worked around by reusing the same DisplayId for
>>> all your vtkRenderWindow (see SetDisplayId/GetDisplayId).
>>>
>>> 2. Once you get pass the first problem, it seem that OpenGL (or nvidia
>>> implementation in my case) has also a limited number of available
>>> context. So when creating a lot of vtkRenderWindow you get:
>>>
>>> ...
>>> The error was 'GLXBadDrawable'.
>>> (Details: serial 403 error_code 158 request_code 143 minor_code 5)
>>> (Note to programmers: normally, X errors are reported asynchronously;
>>> that is, you will receive the error a while after causing it.
>>> To debug your program, run it with the --sync command line
>>> option to change this behavior. You can then get a meaningful
>>> backtrace from your debugger if you break on the gdk_x_error() function.)
>>> ...
>>>
>>> I have not been able to work around this issue. Has anyone deal with
>>> this before ? Is there a solution or at least a work around ?
>>>
>>> Thanks for suggestions !
>>> --
>>> Mathieu
>>> Ps: at least on my machine it seems opengl context are leaked even
>>> after the process was aborted, I cannot even start glxinfo anymore:
>>>
>>>
>>> $ glxinfo
>>> name of display: :0.0
>>> X Error of failed request: GLXBadDrawable
>>> Major opcode of failed request: 143 (GLX)
>>> Minor opcode of failed request: 5 (X_GLXMakeCurrent)
>>> Serial number of failed request: 18
>>> Current serial number in output stream: 18
>>>
>>
>>
>>
>> --
>> Mathieu
>>
>
>
>
> --
> Mathieu
>
--
Mathieu
More information about the vtkusers
mailing list