Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. QOpenGlWidget's ::paintEngine being called from QCoreApplication::processEvents

QOpenGlWidget's ::paintEngine being called from QCoreApplication::processEvents

Scheduled Pinned Locked Moved Solved Game Development
qopenglwidgetpaintengine
11 Posts 2 Posters 2.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Michael Wilson
    wrote on last edited by
    #1

    I'm converting an OSX application from Qt 4/Carbon to Qt5.11 with the QOpenGLWidget.

    I've moved the drawing "calls" to my overridden QOpenGlWidget::paintGL().

    The problem is I'm still getting these messages on the console:

    QWidget::paintEngine: Should no longer be called

    Getting a stack trace, I've discovered that this is being called eventually from QCoreApplication::processEvents, which I'm calling from my own internal event loop.

    Here's a stack trace (edited for readability)

    thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: libQt5Widgets_debug.5.dylibQWidget::paintEngine()
    frame #1: libQt5Widgets_debug.5.dylibQOpenGLWidget::paintEngine(0) frame #2: libQt5Gui_debug.5.dylibQPainter::begin()
    frame #3: libQt5Gui_debug.5.dylibQPainter::QPainter() frame #4: libQt5Gui_debug.5.dylibQPainter::QPainter()
    frame #5: libQt5Widgets_debug.5.dylibQWidgetPrivate::drawWidget() frame #6: libQt5Widgets_debug.5.dylibQWidgetPrivate::repaint_sys()
    frame #7: libQt5Widgets_debug.5.dylibQWidgetPrivate::syncBackingStore() frame #8: libQt5Widgets_debug.5.dylibQWidgetWindow::handleExposeEvent()
    frame #9: libQt5Widgets_debug.5.dylibQWidgetWindow::event() frame #10: libQt5Widgets_debug.5.dylibQApplicationPrivate::notify_helper()
    frame #11: libQt5Widgets_debug.5.dylibQApplication::notify() frame #12: libQt5Core_debug.5.dylibQCoreApplication::notifyInternal2()
    frame #13: libQt5Gui_debug.5.dylibQCoreApplication::sendSpontaneousEvent() frame #14: libQt5Gui_debug.5.dylibQGuiApplicationPrivate::processExposeEvent()
    frame #15: libQt5Gui_debug.5.dylibQGuiApplicationPrivate::processWindowSystemEvent() frame #16: libQt5Gui_debug.5.dylibbool QWindowSystemInterfacePrivate::handleWindowSystemEventQWindowSystemInterface::SynchronousDelivery()
    frame #17: libQt5Gui_debug.5.dylibvoid QWindowSystemInterface::handleExposeEvent() frame #18: libqcocoa_debug.dylibQCocoaWindow::handleExposeEvent()
    frame #19: libqcocoa_debug.dylib::-[QNSView updateRegion:](self=0x000061200039fc40, _cmd="updateRegion:", dirtyRegion=QRegion @ 0x00007ffeefbf9b18) frame #20: libqcocoa_debug.dylib::-[QNSView updateLayer](self=0x000061200039fc40, _cmd="updateLayer")
    frame #21: AppKit_NSViewUpdateLayer + 45 frame #22: AppKit-[_NSViewBackingLayer display] + 495
    frame #23: QuartzCoreCA::Layer::display_if_needed(CA::Transaction*) + 634 frame #24: QuartzCoreCA::Context::commit_transaction(CA::Transaction*) + 319
    frame #25: QuartzCoreCA::Transaction::commit() + 576 frame #26: QuartzCoreCA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 66
    frame #27: CoreFoundationCFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23 frame #28: CoreFoundation__CFRunLoopDoObservers + 452
    frame #29: CoreFoundationCFRunLoopRunSpecific + 523 frame #30: HIToolboxRunCurrentEventLoopInMode + 293
    frame #31: HIToolboxReceiveNextEventCommon + 618 frame #32: HIToolbox_BlockUntilNextEventMatchingListInModeWithFilter + 64
    frame #33: AppKit_DPSNextEvent + 997 frame #34: AppKit-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362
    frame #35: libqcocoa_debug.dylibQCocoaEventDispatcher::processEvents(this=0x00006040000dbdf0, flags=(i = 0)) at qcocoaeventdispatcher.mm:482 frame #36: libQt5Core_debug.5.dylib`QCoreApplication::processEvents(flags=(i = 0)) at qcoreapplication.cpp:1252
    The problem is that ::processEvents is eventually calling ::paintEngine for the QOpenGLWidget, OUTSIDE of ::paintGL, but it's totally out of my control.

    FWIW, the Event driving this is a QEvent::UpdateRequest.

    I tried overriding ::event in my QOpenGLWidget-inheriting class to call QOpenGlWidget::update when it receives a QEvent::UpdateRequest, but that just ended up making the app non-responsive.

    How should I handle ::processEvents attempting to draw QOpenGlWidgets?

    Thanks!

    P.S. Here's a link to the same question on Stack Overflow: https://stackoverflow.com/questions/51561062/

    1 Reply Last reply
    0
    • M Offline
      M Offline
      Michael Wilson
      wrote on last edited by
      #11

      Using the minimal example above, I fixed this by removing this call in our QOpenGlWidget subclass's constructor:

      setAttribute( Qt::WA_PaintOnScreen, true );

      Removing this got rid of the paintengine calls (and numerous other problems).

      Thanks!!!!

      1 Reply Last reply
      1
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi and welcome to devnet,

        Can you share your widget's code ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • M Offline
          M Offline
          Michael Wilson
          wrote on last edited by
          #3

          Sure...here are the relevant QOpenGlWidget methods. I purposely have over-simplified them for now.

          Unfortunately, none of these methods are involved in code path being called. :-(.

          void
          UiEventSourceWidget::initializeGL()
          {
          // Set up the rendering context, load shaders and other resources, etc.:
          initializeOpenGLFunctions();
          bool result;
          uint error;

          error = glGetError();
          Log4(L"UiEventSourceWidget::initializeGL:%d glGetError %d", LINE, error);
          Assert(error == GL_NO_ERROR);

          glClearColor(0.0f, 1.0f, 0.0f, 1.0f);

          error = glGetError();
          Log4(L"UiEventSourceWidget::initializeGL:%d glGetError %d", LINE, error);
          Assert(error == GL_NO_ERROR);

          Log4(L"UiEventSourceWidget::initializeGL:%d context 0x%x, defaultFramebufferObject 0x%x",
          LINE, context(), defaultFramebufferObject());
          }

          void
          UiEventSourceWidget::resizeGL(int w, int h)
          {
          Log4(L"UiEventSourceWidget::resizeGL");
          update();
          }

          void
          UiEventSourceWidget::paintGL()
          {
          Log4(L"UiEventSourceWidget::paintGL QOpenGLContext::currentContext() 0x%x, "
          "defaultFramebufferObject() %d, isValid %s, glGetError() %d",
          QOpenGLContext::currentContext(),
          defaultFramebufferObject(),
          isValid() ? L"True" : L"False",
          glGetError());

          uint error;
          error = glGetError();
          Assert(error == GL_NO_ERROR);
          
          glClear(GL_COLOR_BUFFER_BIT);
          error = glGetError();
          Assert(error == GL_NO_ERROR);
          
          glClear(GL_COLOR_BUFFER_BIT);
          error = glGetError();
          Log4(L"UiEventSourceWidget::paintGL:%d glGetError %d", __LINE__, error);
          Assert(error == GL_NO_ERROR);
          
          windowPainter_->updateEntireWindow();
          
          error = glGetError();
          Log4(L"UiEventSourceWidget::paintGL:%d glGetError %d", __LINE__, error);
          Assert(error == GL_NO_ERROR);
          
          Log4(L"UiEventSourceWidget::paintGL ...exit");
          

          }

          1 Reply Last reply
          0
          • M Offline
            M Offline
            Michael Wilson
            wrote on last edited by
            #4

            FWIW, in QOpenGLWidget::paintEngine(), d->inBackingStorePaint is True.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #5

              By the way, what version of macOS are you running this on ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • M Offline
                M Offline
                Michael Wilson
                wrote on last edited by
                #6

                10.14 (Mojave) but it also failed under High Sierra.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  What is windowPainter_ ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    Michael Wilson
                    wrote on last edited by
                    #8

                    It's the code that does our Rendering.

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      Would it be possible to also see that ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        Michael Wilson
                        wrote on last edited by
                        #10

                        Well, considering that it's rendering an entire Virtual World (There.com) I'm pretty sure it wouldn't fit in one post :-).

                        But, I can replace it with this and get the same problem.

                        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
                        
                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
                        
                        AssertNoGlError();
                        
                        GLint drawFboId = 0, readFboId = 0, drawBoId = 0;
                        glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFboId);
                        glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFboId);
                        glGetIntegerv(GL_DRAW_BUFFER, &drawBoId);
                        
                        Log4(L"PoWglPlatform::openPlatform:%d, drawFboId %d, readFboId %d, drawBoId %d",
                             __LINE__, drawFboId, readFboId, drawBoId);
                        
                        AssertNoGlError();
                        
                        glColor3d(0.0,1.0,0.0);
                        // Draw something static to the back buffer.
                        glBegin(GL_QUADS);
                                glVertex2d(0.0,0.0);glVertex2d(0.10,0.0);glVertex2d(0.10,0.10);glVertex2d(0.0,0.10);
                        glEnd();
                        glFlush();
                        
                        // If this line is uncommented, it proves that
                        // glDrawBuffer(GL_FRONT) is not working!!!!!!!!!!!!
                        //glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
                        
                        //glDrawBuffer(GL_FRONT);
                        
                        float angle=0;
                        for( angle=0;angle<360.0;angle+=2.0)
                        {
                            // This should restore our static drawing.
                            glFlush();
                        
                            float x=sin(angle*M_PI/180.0);
                            float y=cos(angle*M_PI/180.0);
                            glColor3d(1.0,1.0,1.0);
                            glBegin(GL_LINES);
                                glVertex2d(0.0,0.0);
                                glVertex2d(x,y);
                            glEnd();
                        
                            glFinish();
                        }
                        
                        AssertNoGlError();
                        

                        Also, here's ::initializeGL

                        // Set up the rendering context, load shaders and other resources, etc.:
                        initializeOpenGLFunctions();

                        AssertNoGlError();

                        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);

                        FWIW, the screen stays blue ( glClearColor(0.0f, 0.0f, 1.0f, 1.0f); ), and never turns red or draws anything we see in ::paintGL.

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          Michael Wilson
                          wrote on last edited by
                          #11

                          Using the minimal example above, I fixed this by removing this call in our QOpenGlWidget subclass's constructor:

                          setAttribute( Qt::WA_PaintOnScreen, true );

                          Removing this got rid of the paintengine calls (and numerous other problems).

                          Thanks!!!!

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved