[vtk-developers] C++ example (was Re: X Error of failed request: GLXBadDrawable)

Mathieu Malaterre mathieu.malaterre at gmail.com
Mon Jun 30 09:02:46 EDT 2008


When creating a vtkRenderWindowInteractor, it will internally create
the X 'Window' for the RW and then pass it via SetWindowId (thus
RW::OwnWindow is set to 0)

  if (!this->Top)
    {
    depth   = ren->GetDesiredDepth();
    cmap    = ren->GetDesiredColormap();
    vis     = ren->GetDesiredVisual();
    position= ren->GetPosition();

    this->Top = XtVaAppCreateShell(this->RenderWindow->GetWindowName(),"vtk",
                                   applicationShellWidgetClass,
                                   this->DisplayId,
                                   XtNdepth, depth,
                                   XtNcolormap, cmap,
                                   XtNvisual, vis,
                                   XtNx, position[0],
                                   XtNy, position[1],
                                   XtNwidth, size[0],
                                   XtNheight, size[1],
                                   XtNinput, True,
                                   XtNmappedWhenManaged, 0,
                                   NULL);
    this->OwnTop = 1;
    XtRealizeWidget(this->Top);
    XSync(this->DisplayId,False);
    ren->SetWindowId(XtWindow(this->Top));

    XMapWindow(this->DisplayId, XtWindow(this->Top));
    XSync(this->DisplayId,False);
    }

So later on, when RW::Finalize is called the Window never enter (since
OwnWindow==0):


  // then close the old window if we own it
  if (this->OwnWindow && this->DisplayId && this->WindowId)
    {
    XDestroyWindow(this->DisplayId,this->WindowId);
    this->WindowId = static_cast<Window>(NULL);
    }

What is missing here is -I guess- an API to say: RWI->Finalize() ...

Comments ?
-Mathieu

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 vtk-developers mailing list