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>
This commit is contained in:
parent
3a2fdc48ad
commit
684990d148
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
EGLSurface eglSurface;
|
||||
|
||||
QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
|
||||
QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
|
||||
|
||||
EGLSurface eglSurface = screen->eglSurface();
|
||||
|
||||
screen->waitForPageFlipComplete();
|
||||
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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user