[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