diff options
Diffstat (limited to 'src/plugins/platforms/eglfs/api')
10 files changed, 116 insertions, 50 deletions
diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp index a17b567b24..9c10c1a998 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp @@ -22,10 +22,19 @@ QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContex EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) { - if (surface->surface()->surfaceClass() == QSurface::Window) - return static_cast<QEglFSWindow *>(surface)->surface(); - else + if (surface->surface()->surfaceClass() == QSurface::Window) { + + QEglFSWindow *w = static_cast<QEglFSWindow *>(surface); + EGLSurface s = w->surface(); + if (s == EGL_NO_SURFACE) { + w->resetSurface(); + s = w->surface(); + } + return s; + + } else { return static_cast<QEGLPbuffer *>(surface)->pbuffer(); + } } EGLSurface QEglFSContext::createTemporaryOffscreenSurface() diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp index 05a86cee64..1e1a7d8269 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp @@ -8,6 +8,7 @@ #include <qpa/qwindowsysteminterface.h> #include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFunctions> #include <QtCore/QFile> #include <QtCore/QJsonDocument> #include <QtCore/QJsonArray> @@ -117,16 +118,18 @@ void QEglFSCursor::createShaderPrograms() void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image) { + Q_ASSERT(QOpenGLContext::currentContext()); + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); if (!*texture) - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */, - GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); + f->glGenTextures(1, texture); + f->glBindTexture(GL_TEXTURE_2D, *texture); + f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + f->glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */, + GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); } void QEglFSCursor::initCursorAtlas() @@ -309,8 +312,7 @@ void QEglFSCursor::paintOnScreen() // screens are siblings of each other. When not enabled, the sibling list // only contains m_screen itself. for (QPlatformScreen *screen : m_screen->virtualSiblings()) { - if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot) - && QOpenGLContext::currentContext()->screen() == screen->screen()) + if (screen->geometry().contains(cr.topLeft().toPoint() + m_cursor.hotSpot)) { cr.translate(-screen->geometry().topLeft()); const QSize screenSize = screen->geometry().size(); @@ -339,8 +341,8 @@ void QEglFSCursor::paintOnScreen() // to deal with the changes we make. struct StateSaver { - StateSaver() { - f = QOpenGLContext::currentContext()->functions(); + StateSaver(QOpenGLFunctions* func) { + f = func; vaoHelper = QOpenGLVertexArrayObjectHelper::vertexArrayObjectHelperForContext(QOpenGLContext::currentContext()); static bool windowsChecked = false; @@ -366,6 +368,8 @@ struct StateSaver f->glGetIntegerv(GL_BLEND_SRC_ALPHA, blendFunc + 1); f->glGetIntegerv(GL_BLEND_DST_RGB, blendFunc + 2); f->glGetIntegerv(GL_BLEND_DST_ALPHA, blendFunc + 3); + scissor = f->glIsEnabled(GL_SCISSOR_TEST); + stencil = f->glIsEnabled(GL_STENCIL_TEST); f->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBuf); if (vaoHelper->isValid()) f->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao); @@ -389,17 +393,15 @@ struct StateSaver f->glFrontFace(frontFace); if (cull) f->glEnable(GL_CULL_FACE); - else - f->glDisable(GL_CULL_FACE); if (depthTest) f->glEnable(GL_DEPTH_TEST); - else - f->glDisable(GL_DEPTH_TEST); - if (blend) - f->glEnable(GL_BLEND); - else + if (!blend) f->glDisable(GL_BLEND); f->glBlendFuncSeparate(blendFunc[0], blendFunc[1], blendFunc[2], blendFunc[3]); + if (scissor) + f->glEnable(GL_SCISSOR_TEST); + if (stencil) + f->glEnable(GL_STENCIL_TEST); f->glBindBuffer(GL_ARRAY_BUFFER, arrayBuf); if (vaoHelper->isValid()) vaoHelper->glBindVertexArray(vao); @@ -424,6 +426,8 @@ struct StateSaver bool depthTest; bool blend; GLint blendFunc[4]; + bool scissor; + bool stencil; GLint vao; GLint arrayBuf; struct { GLint enabled, type, size, normalized, stride, buffer; GLvoid *pointer; } va[2]; @@ -431,13 +435,12 @@ struct StateSaver void QEglFSCursor::draw(const QRectF &r) { - StateSaver stateSaver; + Q_ASSERT(QOpenGLContext::currentContext()); + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + StateSaver stateSaver(f); QEglFSCursorData &gfx = static_cast<QEglFSContext*>(QOpenGLContext::currentContext()->handle())->cursorData; if (!gfx.program) { - // one time initialization - initializeOpenGLFunctions(); - createShaderPrograms(); if (!gfx.atlasTexture) { @@ -483,13 +486,13 @@ void QEglFSCursor::draw(const QRectF &r) s2, t1 }; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, cursorTexture); + f->glActiveTexture(GL_TEXTURE0); + f->glBindTexture(GL_TEXTURE_2D, cursorTexture); if (stateSaver.vaoHelper->isValid()) stateSaver.vaoHelper->glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); + f->glBindBuffer(GL_ARRAY_BUFFER, 0); gfx.program->enableAttributeArray(0); gfx.program->enableAttributeArray(1); @@ -499,13 +502,15 @@ void QEglFSCursor::draw(const QRectF &r) gfx.program->setUniformValue(gfx.textureEntry, 0); gfx.program->setUniformValue(gfx.matEntry, m_rotationMatrix); - glDisable(GL_CULL_FACE); - glFrontFace(GL_CCW); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top + f->glDisable(GL_CULL_FACE); + f->glFrontFace(GL_CCW); + f->glEnable(GL_BLEND); + f->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + f->glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top + f->glDisable(GL_SCISSOR_TEST); + f->glDisable(GL_STENCIL_TEST); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + f->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); gfx.program->disableAttributeArray(0); gfx.program->disableAttributeArray(1); diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h index 294426067c..88d4ce695a 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h @@ -20,7 +20,6 @@ #include <qpa/qplatformscreen.h> #include <QtOpenGL/QOpenGLShaderProgram> #include <QtGui/QMatrix4x4> -#include <QtGui/QOpenGLFunctions> #include <QtGui/private/qinputdevicemanager_p.h> #include <QtCore/qlist.h> @@ -58,7 +57,6 @@ struct QEglFSCursorData { }; class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor - , protected QOpenGLFunctions { Q_OBJECT public: diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp index 268b9aa093..56fda45e90 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp @@ -65,7 +65,7 @@ static int framebuffer = -1; QByteArray QEglFSDeviceIntegration::fbDeviceName() const { -#ifdef Q_OS_LINUX +#if defined(Q_OS_LINUX) || defined(Q_OS_VXWORKS) QByteArray fbDev = qgetenv("QT_QPA_EGLFS_FB"); if (fbDev.isEmpty()) fbDev = QByteArrayLiteral("/dev/fb0"); @@ -95,7 +95,7 @@ int QEglFSDeviceIntegration::framebufferIndex() const void QEglFSDeviceIntegration::platformInit() { -#ifdef Q_OS_LINUX +#if defined(Q_OS_LINUX) || defined(Q_OS_VXWORKS) QByteArray fbDev = fbDeviceName(); framebuffer = qt_safe_open(fbDev, O_RDONLY); @@ -113,7 +113,7 @@ void QEglFSDeviceIntegration::platformInit() void QEglFSDeviceIntegration::platformDestroy() { -#ifdef Q_OS_LINUX +#if defined(Q_OS_LINUX) || defined(Q_OS_VXWORKS) if (framebuffer != -1) close(framebuffer); #endif diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp index 42cbdf127c..f0b64c475c 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp @@ -110,7 +110,8 @@ void QEglFSIntegration::initialize() void QEglFSIntegration::destroy() { - foreach (QWindow *w, qGuiApp->topLevelWindows()) + const auto toplevels = qGuiApp->topLevelWindows(); + for (QWindow *w : toplevels) w->destroy(); qt_egl_device_integration()->screenDestroy(); @@ -386,6 +387,14 @@ QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) return qt_egl_device_integration()->platformFunction(function); } +QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const +{ + if (hint == QPlatformIntegration::ShowIsFullScreen) + return true; + + return QPlatformIntegration::styleHint(hint); +} + #if QT_CONFIG(evdev) void QEglFSIntegration::loadKeymap(const QString &filename) { diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h index 3e4c57197e..8007167ec7 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h @@ -76,6 +76,8 @@ public: QFunctionPointer platformFunction(const QByteArray &function) const override; + QVariant styleHint(QPlatformIntegration::StyleHint hint) const override; + QFbVtHandler *vtHandler() { return m_vtHandler.data(); } QPointer<QWindow> pointerWindow() { return m_pointerWindow; } diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp index b081406258..c5108be04a 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp @@ -121,7 +121,7 @@ void QEglFSScreen::handleCursorMove(const QPoint &pos) return; // First window is always fullscreen. - if (windows.count() == 1) { + if (windows.size() == 1) { QWindow *window = windows[0]->sourceWindow(); if (platformIntegration->pointerWindow() != window) { platformIntegration->setPointerWindow(window); @@ -131,7 +131,7 @@ void QEglFSScreen::handleCursorMove(const QPoint &pos) } QWindow *enter = nullptr, *leave = nullptr; - for (int i = windows.count() - 1; i >= 0; --i) { + for (int i = windows.size() - 1; i >= 0; --i) { QWindow *window = windows[i]->sourceWindow(); const QRect geom = window->geometry(); if (geom.contains(pos)) { @@ -189,7 +189,7 @@ QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) c return QPixmap::fromImage(img).copy(x, y, width, height); } - foreach (QOpenGLCompositorWindow *w, windows) { + for (QOpenGLCompositorWindow *w : windows) { const QWindow *window = w->sourceWindow(); if (window->winId() == wid) { const QRect geom = window->geometry(); @@ -212,4 +212,22 @@ QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) c return QPixmap(); } +QWindow *QEglFSScreen::topLevelAt(const QPoint &point) const +{ +#ifndef QT_NO_OPENGL + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + const int windowCount = windows.size(); + + // Higher z-order is at the end of the list + for (int i = windowCount - 1; i >= 0; i--) { + QWindow *window = windows[i]->sourceWindow(); + if (window->isVisible() && window->geometry().contains(point)) + return window; + } +#endif + + return QPlatformScreen::topLevelAt(point); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h index 8f1eb91206..bbfc9a9259 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h @@ -54,6 +54,8 @@ public: void handleCursorMove(const QPoint &pos); + QWindow *topLevelAt(const QPoint &point) const override; + private: void setPrimarySurface(EGLSurface surface); diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp index 39c5b3d4bf..306d121cfb 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp @@ -22,6 +22,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug) + QEglFSWindow::QEglFSWindow(QWindow *w) : QPlatformWindow(w), #ifndef QT_NO_OPENGL @@ -162,8 +164,29 @@ void QEglFSWindow::destroy() void QEglFSWindow::invalidateSurface() { if (m_surface != EGL_NO_SURFACE) { - eglDestroySurface(screen()->display(), m_surface); + qCDebug(qLcEglDevDebug) << Q_FUNC_INFO << " about to destroy EGLSurface: " << m_surface; + + bool ok = eglDestroySurface(screen()->display(), m_surface); + + if (!ok) { + qCWarning(qLcEglDevDebug, "QEglFSWindow::invalidateSurface() eglDestroySurface failed!" + " Follow-up errors or memory leaks are possible." + " eglGetError(): %x", eglGetError()); + } + + if (eglGetCurrentSurface(EGL_READ) == m_surface || + eglGetCurrentSurface(EGL_DRAW) == m_surface) { + bool ok = eglMakeCurrent(eglGetCurrentDisplay(), EGL_NO_DISPLAY, EGL_NO_DISPLAY, EGL_NO_CONTEXT); + qCDebug(qLcEglDevDebug) << Q_FUNC_INFO << " due to eglDestroySurface on *currently* bound surface" + << "we just called eglMakeCurrent(..,0,0,0)! It returned: " << ok; + } + + if (screen()->primarySurface() == m_surface) + screen()->setPrimarySurface(EGL_NO_SURFACE); + + m_surface = EGL_NO_SURFACE; + m_flags = m_flags & ~Created; } qt_egl_device_integration()->destroyNativeWindow(m_window); m_window = 0; @@ -240,7 +263,7 @@ void QEglFSWindow::requestActivateWindow() QOpenGLCompositor::instance()->moveToTop(this); #endif QWindow *wnd = window(); - QWindowSystemInterface::handleWindowActivated(wnd, Qt::ActiveWindowFocusReason); + QWindowSystemInterface::handleFocusWindowChanged(wnd, Qt::ActiveWindowFocusReason); QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); } @@ -260,7 +283,7 @@ void QEglFSWindow::lower() #ifndef QT_NO_OPENGL QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QList<QOpenGLCompositorWindow *> windows = compositor->windows(); - if (window()->type() != Qt::Desktop && windows.count() > 1) { + if (window()->type() != Qt::Desktop && windows.size() > 1) { int idx = windows.indexOf(this); if (idx > 0) { compositor->changeWindowIndex(this, idx - 1); diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h index d111042040..e51cd69f3d 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h @@ -70,8 +70,8 @@ public: bool isRaster() const; #ifndef QT_NO_OPENGL - QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; } - void setBackingStore(QOpenGLCompositorBackingStore *backingStore); + QOpenGLCompositorBackingStore *backingStore() const override { return m_backingStore; } + void setBackingStore(QOpenGLCompositorBackingStore *backingStore) override; QWindow *sourceWindow() const override; const QPlatformTextureList *textures() const override; void endCompositing() override; |