[vtkusers] C++ example (was Re: X Error of failed request: GLXBadDrawable)
Mathieu Malaterre
mathieu.malaterre at gmail.com
Fri Jun 27 10:24:03 EDT 2008
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
More information about the vtkusers
mailing list