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

Improve the EGL_BAD_MATCH error on certain circumstance

    XMLWordPrintable

Details

    • Task
    • Resolution: Fixed
    • P1: Critical
    • 6.3.0 Beta2
    • 5.15.1
    • QPA: Wayland
    • None

    Description

      1. Create QQuickView such as m_QuickVew = new QQuickView()

      2. call m_QuickVew->winId()

      3. Some event is happened, run the following code. ( maybe you can use Timer for simulation.)

       m_QuickVew->setColor(QColor(Qt::transparent));
       m_QuickVew->setSoruce("xxx");
      

      4. Some event is happened, run the following code, (maybe you can use Timer for simulation.)

      m_QuickVew->show()
      

      5. EGL_BAD_MATCH error is happened

      6. If we call the m_QuickVew->setColor(QColor(Qt::transparent)); before m_QuickVew->winId(). The EGL_BAD_MATCH error in not happened.


      Regarding this issue, I hope to consider the following issue also be improved.

      • 1) Set QT_WAYLAND_DISABLE_WINDOWDECORATION=1.
      • 2) Create QQuickView or QQuickWindow and call the winId() to get the Wid.
      • 3) The QWaylandEglWindow object is created with following code by the winId().
        QWaylandEglWindow::QWaylandEglWindow(QWindow *window, QWaylandDisplay *display)
            : QWaylandWindow(window, display)
            , m_clientBufferIntegration(static_cast<QWaylandEglClientBufferIntegration *>(mDisplay->clientBufferIntegration()))
        {
            QSurfaceFormat fmt = window->requestedFormat();
            if (mDisplay->supportsWindowDecoration())
                fmt.setAlphaBufferSize(8);
            // m_eglConfig is created without AlphaBuffer. 
            m_eglConfig = q_configFromGLFormat(m_clientBufferIntegration->eglDisplay(), fmt);
            m_format = q_glFormatFromConfig(m_clientBufferIntegration->eglDisplay(), m_eglConfig, fmt);
           ... 
        }
        
      • 4) After then, the application want to change the surface format such as setColor(QColor(Qt::transparent)) by some platform event.
      • 5) And then, the application call the setVisible(true) by some platform event.
      • 6) In this case, the following code is run.
        void QWaylandEglWindow::updateSurface(bool create)
        {
            ...
            if (sizeWithMargins.isEmpty()) {
                ....
            } else {
                if (m_waylandEglWindow) {
                  ... 
                } else if (create && wlSurface() && window()->isVisible()) {  //Note," && window()->isVisible()" is just private patch for our platform.
                   ... 
                }
                if (!m_eglSurface && m_waylandEglWindow && create && window()->isVisible()) { //Note," && window()->isVisible()" is just private patch for our platform.
                    EGLNativeWindowType eglw = (EGLNativeWindowType) m_waylandEglWindow;
                    // Call eglCreateWindowSurface with m_eglConfig which is created by QWaylandEglWindow ctor. 
                   // But now, the surface format of our QWindow has the AlphaBuffer. 
                    m_eglSurface = eglCreateWindowSurface(m_clientBufferIntegration->eglDisplay(), m_eglConfig, eglw, 0);
                    if (Q_UNLIKELY(m_eglSurface == EGL_NO_SURFACE))
                        qCWarning(lcQpaWayland, "Could not create EGL surface (EGL error 0x%x)\n", eglGetError());
                }
            }
        }
        
      • 7) And then, the following code is run for the rendering, the "QWaylandGLContext::makeCurrent: eglError: 3009, this: 0x5564a7d9c0" error is happened.
        bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
        {
            .... 
            QWaylandEglWindow *window = static_cast<QWaylandEglWindow *>(surface);
            EGLSurface eglSurface = window->eglSurface();
        
            if (!window->needToUpdateContentFBO() && (eglSurface != EGL_NO_SURFACE)) {
                if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) {
                    qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
                    return false;
                }
                return true;
            }
        
        • 7.1) I guess that, the gl context of renderer thread is created with updated surface format by 4). But the eglSurface is created with the m_eglConfig. So, I guess that the EGL_BAD_MATCH(eglError: 3009) error is happened.
      • 8) Of course, we can fix this issue like following, call the setColor(QColor(Qt::transparent)) before winId() call. And the following guide line was already mentioned by https://doc.qt.io/qt-5.15/qwindow.html#setFormat

        The surface format will be resolved in the create() function. Calling this function after create() has been called will not re-resolve the surface format of the native surface.

      • 9) But, for the convenience usage for updating the surface format, I hope that the eglSurface is created by updated eglConfiguration with new surface format.

      If you can, please consider the above issue when you improve this issue.

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-97916
          # Subject Branch Project Status CR V

          Activity

            People

              inho Inho Lee
              alex-lee Jaehak Lee
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes