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

Do not try to eglMakeCurrent for unintended case

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 5.15.4
    • 5.15.0, 5.15.1, 5.15.2
    • QPA: Wayland
    • None
    • Linux/Yocto
    • 2c0a03e9aea13831d05ac03996949f888afd5085 (qt/qtwayland/5.15)

    Description

      1. The QSGThreadedRenderLoop::hide can be called at twice, when the QWindowPrivate::setVisible(false) is called.

      • 1.1)
        void QWindowPrivate::setVisible(bool visible)
        {
            //.....
            if (platformWindow)
                platformWindow->setVisible(visible); //QSGThreadedRenderLoop::hide is called 
        
            if (!visible) {
                QHideEvent hideEvent;
                QGuiApplication::sendEvent(q, &hideEvent); //QSGThreadedRenderLoop::hide is called 
            }
        }
        
      • 1.2) The backtrace of first QSGThreadedRenderLoop::hide
        (gdb) bt
        #0  QSGThreadedRenderLoop::hide (this=0x557ece1260, window=0x557ec31bb0)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtdeclarative/src/quick/scenegraph/qsgthreadedrenderloop.cpp:1199
        #1  0x0000007fa1c28c48 in QQuickWindow::event (this=0x557ec31bb0, e=0x7fd749fc90)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtdeclarative/src/quick/items/qquickwindow.cpp:1744
        #2  0x0000007fa0b82224 in QCoreApplication::notifyInternal2 (receiver=0x557ec31bb0, event=0x7fd749fc90)
            at ../../include/QtCore/5.15.0/QtCore/private/../../../../../../../../../../../workspace/sources/qtbase/src/corelib/thread/qthread_p.h:325
        #3  0x0000007fa0b82454 in QCoreApplication::sendEvent (receiver=<optimized out>, event=event@entry=0x7fd749fc90)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtbase/src/corelib/kernel/qcoreapplication.cpp:1456
        #4  0x0000007f9c42e65c in QtWaylandClient::QWaylandWindow::reset (this=this@entry=0x557ee6a260, sendDestroyEvent=sendDestroyEvent@entry=true)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtwayland/src/client/qwaylandwindow.cpp:250
        #5  0x0000007f9c430b78 in QtWaylandClient::QWaylandWindow::setVisible (this=0x557ee6a260, visible=<optimized out>)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtwayland/src/client/qwaylandwindow.cpp:444
        #6  0x0000007fa1477ba4 in QWindowPrivate::setVisible (this=0x557ecb5000, visible=false)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtbase/src/gui/kernel/qwindow.cpp:408
        #7  0x0000007fa20be758 in appcommon::WindowBasePrivate::hide (this=0x557ecc8d40) at ../git/impl/src/WindowBasePrivate.cpp:560
        #8  0x0000007fa0b8d208 in QtPrivate::QSlotObjectBase::call (a=0x7fd749fe00, r=0x557ec31350, this=0x557fd3b2c0)
            at ../../include/QtCore/../../../../../../../../workspace/sources/qtbase/src/corelib/kernel/qobjectdefs_impl.h:398
        #9  QMetaObject::invokeMethodImpl (object=0x557ec31350, slot=0x557fd3b2c0, type=Qt::AutoConnection, ret=0x0)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtbase/src/corelib/kernel/qmetaobject.cpp:1537
        //....
        

      2. The QWaylandGLContext::doneCurrent is called by the first QSGRenderThread::invalidateGraphics.

      • 2.1) The m_context is not reset in the current following code
        void QWaylandGLContext::doneCurrent()
        {
            eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        }
        

      3 .And then wayland surface is destroyed.

      4. After then, the second QSGRenderThread::invalidateGraphics is called, the isValid of QOpenGLContext::makeCurrent do not return the false.

      • 4.1) The backtrace of second QSGThreadedRenderLoop::hide
        #0  QSGThreadedRenderLoop::hide (this=0x557ece1260, window=0x557ec31bb0)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtdeclarative/src/quick/scenegraph/qsgthreadedrenderloop.cpp:1199
        #1  0x0000007fa1477ff8 in QWindow::event (this=this@entry=0x557ec31bb0, ev=ev@entry=0x7fd749fd50)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtbase/src/gui/kernel/qwindow.cpp:2433
        #2  0x0000007fa1c2898c in QQuickWindow::event (this=0x557ec31bb0, e=0x7fd749fd50)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtdeclarative/src/quick/items/qquickwindow.cpp:1782
        #3  0x0000007fa0b82224 in QCoreApplication::notifyInternal2 (receiver=0x557ec31bb0, event=0x7fd749fd50)
            at ../../include/QtCore/5.15.0/QtCore/private/../../../../../../../../../../../workspace/sources/qtbase/src/corelib/thread/qthread_p.h:325
        #4  0x0000007fa0b82454 in QCoreApplication::sendEvent (receiver=receiver@entry=0x557ec31bb0, event=event@entry=0x7fd749fd50)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtbase/src/corelib/kernel/qcoreapplication.cpp:1456
        #5  0x0000007fa1477bc0 in QWindowPrivate::setVisible (this=<optimized out>, visible=false)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtbase/src/gui/kernel/qwindow.cpp:412
        #6  0x0000007fa20be758 in appcommon::WindowBasePrivate::hide (this=0x557ecc8d40) at ../git/impl/src/WindowBasePrivate.cpp:560
        #7  0x0000007fa0b8d208 in QtPrivate::QSlotObjectBase::call (a=0x7fd749fe00, r=0x557ec31350, this=0x557fd3b2c0)
            at ../../include/QtCore/../../../../../../../../workspace/sources/qtbase/src/corelib/kernel/qobjectdefs_impl.h:398
        #8  QMetaObject::invokeMethodImpl (object=0x557ec31350, slot=0x557fd3b2c0, type=Qt::AutoConnection, ret=0x0)
            at /home/alex/disk/Works/yocto/build-ccos/build-pony/workspace/sources/qtbase/src/corelib/kernel/qmetaobject.cpp:1537
        //...
        
      • 4.2) The isValid of QOpenGLContext::makeCurrent do not return the false.
        bool QOpenGLContext::makeCurrent(QSurface *surface)
        {
            Q_D(QOpenGLContext);
            if (!isValid())
                return false;
           ....
        }
        
        bool QWaylandGLContext::isValid() const
        {
            return m_context != EGL_NO_CONTEXT;
        }
        

      5. The eglSurface is EGL_NO_SURFACE in the QWaylandGLContext::makeCurrent is called.

      6. But our GPU support the EGL_KHR_surfaceless_context, and then the eglMakeCurrent((m_eglDisplay, EGL_NO_SURFACE , EGL_NO_SURFACE , m_context) is not return false.

      • So, the QWaylandGLContext::makeCurrent return true. So, the other unnecessary logic is run at this second hide.
      • AFAIK, a lot of modern GPU support the EGL_KHR_surfaceless_context.
      • Our GPU works weird in this case such as the rendering is not worked after QWindow is shown.
      • I guess that this issue is resemble the https://bugs.freedesktop.org/show_bug.cgi?id=96694.

      7. To resolve this issue, Do not try to eglMakeCurrent for unintended case.

      Attachments

        Issue Links

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

          Activity

            People

              qt.team.graphics.and.multimedia Qt Graphics Team
              alex-lee Jaehak Lee
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes