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

Sometimes ShaderEffect types are not be drawn correctly on 2 QQuickWindows

    XMLWordPrintable

Details

    • Linux/Wayland, Linux/X11
    • d7d44783ce (qt/qtdeclarative/dev) d7d44783ce (qt/tqtc-qtdeclarative/dev) 252181407d (qt/qtdeclarative/6.4) d7d44783ce (qt/qtdeclarative/wip/material3) 252181407d (qt/tqtc-qtdeclarative/6.4)

    Description

      Sometimes FastBlur and OpacityMask(using ShaderEffect internally) are not be drawn correctly on 2 QQuickWindows

      In condition:

      1. the first window with FastBlur and OpacityMask types don't hide.
      2. the second window(both isPersistentGraphics and isPersistentSceneGraph are false) is shown and hidden repeatably.
      3. the first window loads a component which has FastBlur and OpacityMask and unloads repeatably.

      How to use the attached example:

      1. wait for the second window to be shown.
      2. click the first window after the second window is hidden.
      3. click the first window at appropriate intervals until this problem is reproduced.

      The cause of the problem:
      QSGRhiShaderMaterialTypeCache is not managed by each a QQuickWidow(or QSGRenderContext). All QQuickWindows use the same QSGRhiShaderMaterialTypeCache. So, in multi windows environment, if a window clear the QSGRhiShaderMaterialTypeCache at some point, ShaderEffect types of another window may be rendered incorrectly.

       The simplest way to resolve this problem is:

          don't clear QSGRhiShaderMaterialTypeCache in any cases.

      // qtdeclarative/src/quick/scenegraph/qsgthreadedrenderloop.cpp
      
       void QSGRenderThread::invalidateGraphics(QQuickWindow *window, bool inDestructor)
       {
           qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "invalidateGraphics()");    
      
           if (!rhi)
               return;    
      
           if (!window) {
               qCWarning(QSG_LOG_RENDERLOOP, "QSGThreadedRenderLoop:QSGRenderThread: no window to make current...");
               return;
           }
           bool wipeSG = inDestructor || !window->isPersistentSceneGraph();
           bool wipeGraphics = inDestructor || (wipeSG && !window->isPersistentGraphics());    
      
           bool current = true;
           if (rhi)
               rhi->makeThreadLocalNativeContextCurrent();    
      
           if (Q_UNLIKELY(!current)) {
               qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- cleanup without an OpenGL context");
           }    
      
           QQuickWindowPrivate *dd = QQuickWindowPrivate::get(window);    
      
           // The canvas nodes must be cleaned up regardless if we are in the destructor..
           if (wipeSG) {
               dd->cleanupNodesOnShutdown();
      - #if QT_CONFIG(quick_shadereffect)
      -         QSGRhiShaderEffectNode::cleanupMaterialTypeCache();
      - #endif
           } else {
               qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent SG, avoiding  cleanup");
               return;
           }
      
      

        

      any good ideas?

      Attachments

        Activity

          People

            lagocs Laszlo Agocs
            dekim dennis kim
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: