summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.cpp1
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.h2
-rw-r--r--src/plugins/platforms/kms/qkmscontext.cpp35
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp42
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h21
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.cpp3
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.h4
-rw-r--r--src/plugins/platforms/kms/qkmswindow.cpp5
-rw-r--r--src/plugins/platforms/kms/qkmswindow.h3
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 &region, 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;