Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-19977

QEgl::getCompatibleVisualId returns incorrect VisualID for secondary display




      EGL implementations are supposed to provide a list of valid EGLConfig's which are
      used for rendering. These configs define information such as what types of
      surfaces the config can be used to render to (windows, pixmaps, pbuffers), what
      the pixel format is, whether a depth/stencil buffer is present, etc. One of
      the attributes of an EGL config is a native visual which can be used to create
      compatible native windows for the specified config. So an EGL app is supposed
      to select an EGLConfig and then create an X window using the visual ID
      suggested by the config.

      In some cases the EGL implementation may not provide an EGLConfig that exactly matches the characteristics being requested. Some drivers return a default visual adaptable to multiple configuration parameters expecting the EGL application to use the visual without a careful examination of its characteristics. QT correctly rejects these incompatible configs and then trys to figure out an appropriate visual on its own by querying the driver via xrender. In general QT's fallback approach described above should be fine. However QT's logic neglects to trim the list of possible visuals down to only those visuals available on the current screen. It simply picks the first visual that appears to be compatible without checking which screen it's tied to, and uses that. When the application is running on the secondary screen this selection process may result in QT picking a visual from the primary screen (Screen 0). QT will then use that visual to try to create its new window. However when the window being created is on Screen 1 instead, X rejects the window creation (invalid visual for screen). QT does not notice that window creation failed (its X error handler prints the contents of the X error raised, but performs no recovery) and submits subsequent X11 operations referencing the non-existent window. Ultimately it performs a XGetWindowAttributes() call (which returns a bogus window attribute structure since the window does not exist), pulls a bogus visual out of that garbage structure, and tries to pass that to XVisualIDFromVisual. Since the visual structure is garbage, this finally results in a segfault for the client process.

      This issue was found in MeeGo using the meego-ux-* components on a platform with an IMG technology driver for a PVR core. It is reported as https://bugs.meego.com/show_bug.cgi?id=18914

      One of the QT experts should take a look, but it is possible the fix should go in
      QEgl::getCompatibleVisualId() (in gui/egl/qegl_x11.cpp). There's a place
      partway down the function that says "If EGL didn't give us a valid visual ID,
      try XRender." That goes on to generate a list of all TrueColor visuals and
      then walk through the list until it finds one where all of the the color
      component sizes match. As soon as it finds one where all of the color
      components look good, it breaks out of the loop and just uses that visual.
      However just matching colors isn't enough...it should also be making sure the
      visual is appropriate for the screen.

      I think something like this would do the trick (completely untested):

      — gui/egl/qegl_x11.cpp.orig 2011-06-16 15:33:27.000000000 -0700
      +++ gui/egl/qegl_x11.cpp 2011-06-16 15:32:47.000000000 -0700
      @@ -240,11 +240,12 @@
      memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));

      visualInfoTemplate.c_class = TrueColor;
      + visualInfoTemplate.screen = DefaultScreen(X11->display);

      XVisualInfo *matchingVisuals;
      int matchingCount = 0;
      matchingVisuals = XGetVisualInfo(X11->display,

      • VisualClassMask,
        + VisualClassMask | VisualScreenMask,

      farther down the function there's yet another fallback for the case where
      XRender isn't available or fails to select a valid visual. Technically that
      case should also be updated in the same way to filter on screen number,
      although my diff above doesn't cover that.


        No reviews matched the request. Check your Options in the drop-down menu of this sections header.



            Unassigned Unassigned
            joelclark Joel Clark
            1 Vote for this issue
            2 Start watching this issue



                Gerrit Reviews

                There are no open Gerrit changes