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

        1. wayland_test.tar.gz
          4 kB
          Seokha Ko
        2. wayland_test2.tar.gz
          4 kB
          Seokha Ko

        Issue Links

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

          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