Poor QOpenGLWidget performance on OS X, QOpenGLWindow question



  • Hi!

    I have a problem in QOpenGLWidget performance on OS X (MacBook Pro Late 2013 Retina). As I understand QOpenGLWidget have to do full window composition before displaying its content. I have tried using QOpenGLWindow and it works MUCH faster on Mac & Windows. I need to use it embedded inside regular QWidget UI. But its not clear how to forward QOpenGLWindow's events to parent underlaying widget. Underlaying widget actions also aren't working because QOpenGLWindow stealing focus, and there's no way to add an action directly to QOpenGLWindow. Is it possible to use QOpenGLWindow just for displaying content, and make it transparent for all input events? Qt::WindowTransparentForInput flag didn't help.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    From your description, you might be experiencing something similar to that bug . Is this the case ?



  • Hi!

    The bug says about top level windows, also the window there is translucent, but my window is embedded using QWidget::createWindowContainer (not a top level window) and must be completely opaque for performance reason. I have checkout Windows code and find out that WindowTransparentForInput works only for top level windows:

    https://github.com/qtproject/qtbase/blob/5bfac9d653357c906946563b9494d7ae69cdad92/src/plugins/platforms/windows/qwindowswindow.cpp#L539

    With WS_EX_TRANSPARENT flag it also use WS_EX_LAYERED which will decrease performance.

    UPDATE: I tried to use Win32 API call to enable WS_EX_TRANSPARENT - unfortunately underlaying widget still not getting events.

    Andrew.


  • Lifetime Qt Champion

    Then you could install an event filter on it and ignore everything keyboard/mouse related.



  • This doesn't work too, event just goes nowhere. I'm thinking about posting the event back to the QMainWindow by QApplication::sendEvent.


  • Lifetime Qt Champion

    How did you setup the event filter ?



  • @SGaist

    I have minized the code. When I click on the left green side (QOpenGLWindow) I get this error on Windows in app's output and also don't get any events from mouse (mousePressEvent, contextMenuEvent, wheelEvent, ...):

    requestActivate() called for QOpenGLWindow(0x8f8400f450) which has Qt::WindowDoesNotAcceptFocus set.

    On OSX everything seems work fine. Don't know how this works on Linux. Using Qt 5.5.0 open source.

    
    #include <QApplication>
    #include <QOpenGLWindow>
    #include <QOpenGLFunctions>
    #include <QAction>
    #include <QDebug>
    
    class OpenGLWindow : public QOpenGLWindow, protected QOpenGLFunctions
    {
        Q_OBJECT
    
    public:
    
        OpenGLWindow()
        {
            setFlags(flags() | Qt::WindowDoesNotAcceptFocus | Qt::WindowTransparentForInput);
        }
    
        void initializeGL()
        {
            initializeOpenGLFunctions();
        }
    
        void paintGL()
        {
            glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
        }
    
    };
    
    class MainWidget : public QWidget
    {
        Q_OBJECT
    
        OpenGLWindow *openGLWindow;
    
    public:
    
        MainWidget() :
            openGLWindow(new OpenGLWindow())
        {
            QWidget *widget = QWidget::createWindowContainer(openGLWindow, this);
            // widget->setAttribute(Qt::WA_TransparentForMouseEvents);
    
            widget->setFixedSize(200, 300);
    
            setFocusPolicy(Qt::StrongFocus);
    
            setFixedSize(400, 300);
    
            QAction *action = new QAction(tr("Some Action"), this);
            action->setShortcut(QKeySequence(Qt::Key_A));
            action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
            addAction(action);
            connect(action, SIGNAL(triggered()), this, SLOT(onAction()));
        }
    
        void contextMenuEvent(QContextMenuEvent *e)
        {
            qDebug() << "Context menu event";
    
            QWidget::contextMenuEvent(e);
        }
    
        void wheelEvent(QWheelEvent *e)
        {
            qDebug() << "Mouse wheel event";
    
            QWidget::wheelEvent(e);
        }
    
        void mousePressEvent(QMouseEvent *e)
        {
    		qDebug() << "Mouse press event";
    
            QWidget::mousePressEvent(e);
        }
    
        void keyPressEvent(QKeyEvent *e)
        {
            qDebug() << "Key press event";
    
    		QWidget::keyPressEvent(e);
        }
    
    private slots:
    
        void onAction()
        {
    		qDebug() << "Action event";
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        MainWidget w;
        w.show();
    
        return a.exec();
    }
    
    // Avoid linker error
    #include "main.moc"
    

    Also please create empty main_p.h to avoid linker error.


  • Lifetime Qt Champion

    What setup do you have on Windows ? MultiScreen ? Graphic card ?



  • @SGaist

    Windows 8.1, NVIDIA GeForce 660M, single display.

    The problem is about routing of events, not graphics actually.


  • Lifetime Qt Champion

    Indeed, but having a multiple-screen setup might also influence things a bit.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.