diff options
author | Laszlo Agocs <laszlo.agocs@digia.com> | 2014-09-26 14:07:31 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@digia.com> | 2014-09-30 18:23:08 +0200 |
commit | 684990d1481b0858489596dc7b28310bb87a6dfa (patch) | |
tree | 29f6b2df7a35d610e71315cdc01e2a8b82ba9380 | |
parent | 3a2fdc48ad1066eb043f83024ddd76098f933d3a (diff) |
kms: Support QOpenGLWidget and QQuickWidget
Also fixes the handling of shareContext() for contexts and format() for windows
and makes QOffscreenSurface working.
Change-Id: I3c3374a9de14a5b8428de3e11d9d7e1285c5b9c7
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
-rw-r--r-- | src/plugins/platforms/kms/qkmsbackingstore.cpp | 1 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmsbackingstore.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmscontext.cpp | 35 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmsintegration.cpp | 42 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmsintegration.h | 21 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmsscreen.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmsscreen.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmswindow.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/kms/qkmswindow.h | 3 |
9 files changed, 99 insertions, 17 deletions
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp index 29a673b876..ee79145671 100644 --- a/src/plugins/platforms/kms/qkmsbackingstore.cpp +++ b/src/plugins/platforms/kms/qkmsbackingstore.cpp @@ -49,7 +49,6 @@ QKmsBackingStore::QKmsBackingStore(QWindow *window) m_context->setFormat(window->requestedFormat()); m_context->setScreen(window->screen()); m_context->create(); - window->setSurfaceType(QSurface::OpenGLSurface); } QKmsBackingStore::~QKmsBackingStore() diff --git a/src/plugins/platforms/kms/qkmsbackingstore.h b/src/plugins/platforms/kms/qkmsbackingstore.h index 91c04c32d0..56d57313e8 100644 --- a/src/plugins/platforms/kms/qkmsbackingstore.h +++ b/src/plugins/platforms/kms/qkmsbackingstore.h @@ -56,6 +56,8 @@ public: void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size, const QRegion &staticContents); + QImage toImage() const Q_DECL_OVERRIDE { return m_image; } + private: QOpenGLContext *m_context; QImage m_image; diff --git a/src/plugins/platforms/kms/qkmscontext.cpp b/src/plugins/platforms/kms/qkmscontext.cpp index c3a4923ce1..4b4505294c 100644 --- a/src/plugins/platforms/kms/qkmscontext.cpp +++ b/src/plugins/platforms/kms/qkmscontext.cpp @@ -35,19 +35,18 @@ #include "qkmsdevice.h" #include "qkmscontext.h" #include "qkmswindow.h" +#include "qkmsintegration.h" -#include <QOpenGLContext> - +#include <QtGui/QOpenGLContext> #include <QtPlatformSupport/private/qeglconvenience_p.h> QT_BEGIN_NAMESPACE QKmsContext::QKmsContext(QOpenGLContext *context, QKmsDevice *device) - : QPlatformOpenGLContext() - , m_device(device) + : m_device(device) { EGLDisplay display = m_device->eglDisplay(); - EGLConfig config = q_configFromGLFormat(display, QKmsScreen::tweakFormat(context->format()), true); + EGLConfig config = q_configFromGLFormat(display, QKmsScreen::tweakFormat(context->format())); m_format = q_glFormatFromConfig(display, config); //Initialize EGLContext @@ -57,7 +56,12 @@ QKmsContext::QKmsContext(QOpenGLContext *context, QKmsDevice *device) }; eglBindAPI(EGL_OPENGL_ES_API); - m_eglContext = eglCreateContext(display, config, 0, contextAttribs); + + EGLContext share = EGL_NO_CONTEXT; + if (context->shareContext()) + share = static_cast<QKmsContext *>(context->shareContext()->handle())->eglContext(); + + m_eglContext = eglCreateContext(display, config, share, contextAttribs); if (m_eglContext == EGL_NO_CONTEXT) { qWarning("QKmsContext::QKmsContext(): eglError: %x, this: %p", eglGetError(), this); @@ -72,16 +76,19 @@ bool QKmsContext::isValid() const bool QKmsContext::makeCurrent(QPlatformSurface *surface) { - Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(surface->surface()->supportsOpenGL()); EGLDisplay display = m_device->eglDisplay(); - - QPlatformWindow *window = static_cast<QPlatformWindow *>(surface); - QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window())); - - EGLSurface eglSurface = screen->eglSurface(); - - screen->waitForPageFlipComplete(); + EGLSurface eglSurface; + + if (surface->surface()->surfaceClass() == QSurface::Window) { + QPlatformWindow *window = static_cast<QPlatformWindow *>(surface); + QKmsScreen *screen = static_cast<QKmsScreen *>(QPlatformScreen::platformScreenForWindow(window->window())); + eglSurface = screen->eglSurface(); + screen->waitForPageFlipComplete(); + } else { + eglSurface = static_cast<QKmsOffscreenWindow *>(surface)->surface(); + } bool ok = eglMakeCurrent(display, eglSurface, eglSurface, m_eglContext); if (!ok) diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp index ed6ab8f885..d94d7d9aaa 100644 --- a/src/plugins/platforms/kms/qkmsintegration.cpp +++ b/src/plugins/platforms/kms/qkmsintegration.cpp @@ -48,10 +48,13 @@ #include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> #include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> #include <QtPlatformSupport/private/qfbvthandler_p.h> +#include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/QOpenGLContext> #include <QtGui/QScreen> +#include <QtGui/QOffscreenSurface> +#include <qpa/qplatformoffscreensurface.h> QT_BEGIN_NAMESPACE @@ -116,6 +119,7 @@ bool QKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const case ThreadedPixmaps: return true; case OpenGL: return true; case ThreadedOpenGL: return false; + case RasterGLSurface: return true; default: return QPlatformIntegration::hasCapability(cap); } } @@ -138,6 +142,44 @@ QPlatformBackingStore *QKmsIntegration::createPlatformBackingStore(QWindow *wind return new QKmsBackingStore(window); } +// Neither a pbuffer nor a hidden QWindow is suitable. Just use an additional, small gbm surface. +QKmsOffscreenWindow::QKmsOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface) + : QPlatformOffscreenSurface(offscreenSurface) + , m_format(format) + , m_display(display) + , m_surface(EGL_NO_SURFACE) + , m_window(0) +{ + QKmsScreen *screen = static_cast<QKmsScreen *>(offscreenSurface->screen()->handle()); + m_window = gbm_surface_create(screen->device()->gbmDevice(), + 10, 10, + GBM_FORMAT_XRGB8888, + GBM_BO_USE_RENDERING); + if (!m_window) { + qWarning("QKmsOffscreenWindow: Failed to create native window"); + return; + } + + EGLConfig config = q_configFromGLFormat(m_display, m_format); + m_surface = eglCreateWindowSurface(m_display, config, m_window, 0); + if (m_surface != EGL_NO_SURFACE) + m_format = q_glFormatFromConfig(m_display, config); +} + +QKmsOffscreenWindow::~QKmsOffscreenWindow() +{ + if (m_surface != EGL_NO_SURFACE) + eglDestroySurface(m_display, m_surface); + if (m_window) + gbm_surface_destroy((gbm_surface *) m_window); +} + +QPlatformOffscreenSurface *QKmsIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const +{ + QKmsScreen *screen = static_cast<QKmsScreen *>(surface->screen()->handle()); + return new QKmsOffscreenWindow(screen->device()->eglDisplay(), QKmsScreen::tweakFormat(surface->format()), surface); +} + QPlatformFontDatabase *QKmsIntegration::fontDatabase() const { return m_fontDatabase; diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h index b13fbb2793..3ca2510e68 100644 --- a/src/plugins/platforms/kms/qkmsintegration.h +++ b/src/plugins/platforms/kms/qkmsintegration.h @@ -36,7 +36,9 @@ #include <qpa/qplatformintegration.h> #include <qpa/qplatformnativeinterface.h> +#include <qpa/qplatformoffscreensurface.h> #include <QtPlatformSupport/private/qdevicediscovery_p.h> +#include <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -44,6 +46,24 @@ class QKmsScreen; class QKmsDevice; class QFbVtHandler; +class QKmsOffscreenWindow : public QPlatformOffscreenSurface +{ +public: + QKmsOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface); + ~QKmsOffscreenWindow(); + + QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; } + bool isValid() const Q_DECL_OVERRIDE { return m_surface != EGL_NO_SURFACE; } + + EGLSurface surface() const { return m_surface; } + +private: + QSurfaceFormat m_format; + EGLDisplay m_display; + EGLSurface m_surface; + EGLNativeWindowType m_window; +}; + class QKmsIntegration : public QObject, public QPlatformIntegration { Q_OBJECT @@ -58,6 +78,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE; QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp index acc52ae5da..ddcdd10928 100644 --- a/src/plugins/platforms/kms/qkmsscreen.cpp +++ b/src/plugins/platforms/kms/qkmsscreen.cpp @@ -170,10 +170,11 @@ QSurfaceFormat QKmsScreen::tweakFormat(const QSurfaceFormat &format) void QKmsScreen::initializeWithFormat(const QSurfaceFormat &format) { EGLDisplay display = m_device->eglDisplay(); - EGLConfig config = q_configFromGLFormat(display, tweakFormat(format), true); + EGLConfig config = q_configFromGLFormat(display, tweakFormat(format)); m_eglWindowSurface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_gbmSurface, NULL); qCDebug(lcQpaScreen) << "created window surface"; + m_surfaceFormat = q_glFormatFromConfig(display, config); } void QKmsScreen::swapBuffers() diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h index 40661ef709..552541503c 100644 --- a/src/plugins/platforms/kms/qkmsscreen.h +++ b/src/plugins/platforms/kms/qkmsscreen.h @@ -48,6 +48,7 @@ extern "C" { #include <EGL/egl.h> #include <EGL/eglext.h> #include <QtGui/qopengl.h> +#include <QtGui/qsurfaceformat.h> #include <QtCore/qloggingcategory.h> #include <qpa/qplatformscreen.h> @@ -87,6 +88,8 @@ public: static QSurfaceFormat tweakFormat(const QSurfaceFormat &format); + QSurfaceFormat surfaceFormat() const { return m_surfaceFormat; } + private: void performPageFlip(); void initializeScreenMode(const drmModeRes *resources, const drmModeConnector *connector); @@ -111,6 +114,7 @@ private: EGLSurface m_eglWindowSurface; bool m_modeSet; + QSurfaceFormat m_surfaceFormat; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/kms/qkmswindow.cpp b/src/plugins/platforms/kms/qkmswindow.cpp index d2c3bb78fe..bc803d0dbb 100644 --- a/src/plugins/platforms/kms/qkmswindow.cpp +++ b/src/plugins/platforms/kms/qkmswindow.cpp @@ -58,4 +58,9 @@ void QKmsWindow::setGeometry(const QRect &rect) QPlatformWindow::setGeometry(fullscreenRect); } +QSurfaceFormat QKmsWindow::format() const +{ + return static_cast<QKmsScreen *>(m_screen)->surfaceFormat(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/kms/qkmswindow.h b/src/plugins/platforms/kms/qkmswindow.h index fd6f568580..ca7eb209db 100644 --- a/src/plugins/platforms/kms/qkmswindow.h +++ b/src/plugins/platforms/kms/qkmswindow.h @@ -45,7 +45,8 @@ class QKmsWindow : public QPlatformWindow public: QKmsWindow(QWindow *window); - void setGeometry(const QRect &rect); + void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; + QSurfaceFormat format() const Q_DECL_OVERRIDE; private: QPlatformScreen *m_screen; |