summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/kms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/kms')
-rw-r--r--src/plugins/platforms/kms/kms.pro42
-rw-r--r--src/plugins/platforms/kms/main.cpp72
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.cpp72
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.h65
-rw-r--r--src/plugins/platforms/kms/qkmsbuffermanager.cpp198
-rw-r--r--src/plugins/platforms/kms/qkmsbuffermanager.h105
-rw-r--r--src/plugins/platforms/kms/qkmscontext.cpp113
-rw-r--r--src/plugins/platforms/kms/qkmscontext.h75
-rw-r--r--src/plugins/platforms/kms/qkmscursor.cpp131
-rw-r--r--src/plugins/platforms/kms/qkmscursor.h74
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.cpp163
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.h87
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp138
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h82
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.cpp224
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.h97
-rw-r--r--src/plugins/platforms/kms/qkmswindow.cpp64
-rw-r--r--src/plugins/platforms/kms/qkmswindow.h62
18 files changed, 1864 insertions, 0 deletions
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
new file mode 100644
index 0000000000..73a3fa0418
--- /dev/null
+++ b/src/plugins/platforms/kms/kms.pro
@@ -0,0 +1,42 @@
+TARGET = qkms
+
+load(qt_plugin)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+QT = core-private gui-private platformsupport-private opengl-private
+
+CONFIG += link_pkgconfig qpa/genericunixfontdatabase
+
+PKGCONFIG += libdrm egl gbm glesv2
+
+SOURCES = main.cpp \
+ qkmsintegration.cpp \
+ qkmsscreen.cpp \
+ qkmscontext.cpp \
+ qkmswindow.cpp \
+ qkmscursor.cpp \
+ qkmsdevice.cpp \
+ qkmsbuffermanager.cpp \
+ qkmsbackingstore.cpp
+HEADERS = qkmsintegration.h \
+ qkmsscreen.h \
+ qkmscontext.h \
+ qkmswindow.h \
+ qkmscursor.h \
+ qkmsdevice.h \
+ qkmsbuffermanager.h \
+ qkmsbackingstore.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/platforms/kms/main.cpp b/src/plugins/platforms/kms/main.cpp
new file mode 100644
index 0000000000..a07f1645dc
--- /dev/null
+++ b/src/plugins/platforms/kms/main.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QPlatformIntegrationPlugin>
+#include "qkmsintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QKmsIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QKmsIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "kms";
+ return list;
+}
+
+QPlatformIntegration *QKmsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "kms")
+ return new QKmsIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(kms, QKmsIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp
new file mode 100644
index 0000000000..eb682e8ab3
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbackingstore.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsbackingstore.h"
+
+QT_BEGIN_NAMESPACE
+
+QKmsBackingStore::QKmsBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+}
+
+QPaintDevice *QKmsBackingStore::paintDevice()
+{
+ return &m_image;
+}
+
+void QKmsBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ //'window' can be a child window, in which case 'region' is in child window coordinates and
+ // offset is the (child) window's offset in relation to the window surface.
+
+ Q_UNUSED(region)
+ Q_UNUSED(offset)
+ Q_UNUSED(window)
+}
+
+void QKmsBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents)
+ m_image = QImage(size, QImage::Format_RGB32);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.h b/src/plugins/platforms/kms/qkmsbackingstore.h
new file mode 100644
index 0000000000..e270d04db0
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbackingstore.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBACKINGSTORE_KMS_H
+#define QBACKINGSTORE_KMS_H
+
+#include <QtGui/QPlatformBackingStore>
+#include <QImage>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsBackingStore : public QPlatformBackingStore
+{
+public:
+ QKmsBackingStore(QWindow *window);
+
+ QPaintDevice *paintDevice();
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+
+private:
+ QImage m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/kms/qkmsbuffermanager.cpp b/src/plugins/platforms/kms/qkmsbuffermanager.cpp
new file mode 100644
index 0000000000..0c2eec0f3b
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbuffermanager.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsbuffermanager.h"
+#include "qkmsscreen.h"
+#include "qkmscontext.h"
+#include "qkmsdevice.h"
+
+QT_BEGIN_NAMESPACE
+
+QKmsBufferManager::QKmsBufferManager(QKmsScreen *screen) :
+ m_screen(screen),
+ m_frameBufferObject(0),
+ m_renderTarget(0),
+ m_displayCanidate(0),
+ m_currentDisplay(0)
+{
+}
+
+QKmsBufferManager::~QKmsBufferManager()
+{
+ clearBuffers();
+ glDeleteFramebuffers(1, &m_frameBufferObject);
+}
+
+void QKmsBufferManager::setupBuffersForMode(const drmModeModeInfo &mode, int numBuffers)
+{
+ eglMakeCurrent(m_screen->device()->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_screen->device()->eglContext());
+ m_screen->bindFramebuffer();
+
+
+ if (m_frameBufferObject) {
+ clearBuffers();
+ } else {
+ //Setup Framebuffer Object
+ glGenFramebuffers(1, &m_frameBufferObject);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject);
+ }
+
+ //Setup shared Depth/Stencil buffer
+ glGenRenderbuffers(1, &m_depthAndStencilBufferObject);
+ glBindRenderbuffer(GL_RENDERBUFFER, m_depthAndStencilBufferObject);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES,
+ mode.hdisplay, mode.vdisplay);
+
+ //Setup "numBuffer" many rendering targets
+ for (int i = 0; i < numBuffers; i++) {
+ QKmsFramebuffer *buffer = new QKmsFramebuffer();
+
+ glGenRenderbuffers(1, &buffer->renderBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, buffer->renderBuffer);
+
+ buffer->graphicsBufferObject = gbm_bo_create(m_screen->device()->gbmDevice(),
+ mode.hdisplay, mode.vdisplay,
+ GBM_BO_FORMAT_XRGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ buffer->eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR,
+ buffer->graphicsBufferObject, 0);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, buffer->eglImage);
+
+ quint32 stride = gbm_bo_get_pitch(buffer->graphicsBufferObject);
+ quint32 handle = gbm_bo_get_handle(buffer->graphicsBufferObject).u32;
+
+ int status = drmModeAddFB(m_screen->device()->fd(), mode.hdisplay, mode.vdisplay,
+ 32, 32, stride, handle, &buffer->framebufferId);
+ //Todo: IF this returns true, then this is one less buffer that we use
+ //Not so fatal, but not handled at the moment.
+ if (status)
+ qFatal("failed to add framebuffer");
+ m_framebuffers.append(buffer);
+ }
+ //Attach the Depth and Stencil buffer
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
+ m_depthAndStencilBufferObject);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
+ m_depthAndStencilBufferObject);
+ //Attach renderbuffer as Color Attachment.
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ this->renderTargetBuffer());
+}
+
+void QKmsBufferManager::clearBuffers()
+{
+ //Make sure that the FBO is binded
+ glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject);
+ //Detach the Color/Depth/Stencil Attachments.
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
+ 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
+ 0);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ //Delete the shared Depth/Stencil buffer
+ glDeleteRenderbuffers(1, &m_depthAndStencilBufferObject);
+
+ //Delete each renderbuffer object
+ //Delete each EGLImage
+ //Remove each drm Framebuffer
+ foreach (QKmsFramebuffer *buffer, m_framebuffers) {
+ glDeleteRenderbuffers(1, &buffer->renderBuffer);
+ eglDestroyImageKHR(m_screen->device()->eglDisplay(), buffer->eglImage);
+ drmModeRmFB(m_screen->device()->fd(), buffer->framebufferId);
+ delete buffer;
+ }
+ m_framebuffers.clear();
+}
+
+GLuint QKmsBufferManager::renderTargetBuffer()
+{
+ //TODO: Handle more senarios than assuming at least 2 buffers
+ if (!m_renderTarget) {
+ m_renderTarget = m_framebuffers.at(1);
+ }
+ return m_renderTarget->renderBuffer;
+}
+
+quint32 QKmsBufferManager::displayFramebufferId()
+{
+ if (!m_currentDisplay) {
+ m_currentDisplay = m_framebuffers.at(0);
+ m_currentDisplay->available = false;
+ return m_currentDisplay->framebufferId;
+ }
+
+ if (!m_displayCanidate)
+ return m_currentDisplay->framebufferId;
+
+ m_currentDisplay->available = true;
+ m_displayCanidate->available = false;
+ m_currentDisplay = m_displayCanidate;
+ return m_currentDisplay->framebufferId;
+
+}
+
+bool QKmsBufferManager::nextBuffer()
+{
+ m_displayCanidate = m_renderTarget;
+ foreach (QKmsFramebuffer *buffer, m_framebuffers) {
+ if (buffer->available && buffer != m_displayCanidate) {
+ m_renderTarget = buffer;
+ return true;
+ }
+ }
+ return false;
+}
+
+QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbuffermanager.h b/src/plugins/platforms/kms/qkmsbuffermanager.h
new file mode 100644
index 0000000000..59db7ebeb1
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbuffermanager.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSBUFFERMANAGER_H
+#define QKMSBUFFERMANAGER_H
+
+#include <QObject>
+#include <QList>
+
+#define EGL_EGLEXT_PROTOTYPES 1
+#define GL_GLEXT_PROTOTYPES 1
+
+extern "C" {
+#include <gbm.h>
+#include <xf86drmMode.h>
+#include <xf86drm.h>
+}
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreen;
+
+class QKmsFramebuffer
+{
+public:
+ QKmsFramebuffer() : available(true) {}
+ gbm_bo *graphicsBufferObject;
+ GLuint renderBuffer;
+ EGLImageKHR eglImage;
+ quint32 framebufferId;
+ bool available;
+};
+
+
+class QKmsBufferManager
+{
+public:
+ explicit QKmsBufferManager(QKmsScreen *screen);
+ ~QKmsBufferManager();
+ void setupBuffersForMode(const drmModeModeInfo &mode, int numBuffers = 3);
+ GLuint framebufferObject() const { return m_frameBufferObject; }
+ quint32 displayFramebufferId();
+ GLuint renderTargetBuffer();
+ bool nextBuffer();
+
+private:
+ void clearBuffers();
+
+ QKmsScreen *m_screen;
+ QList<QKmsFramebuffer*> m_framebuffers;
+ GLuint m_frameBufferObject;
+ GLuint m_depthAndStencilBufferObject;
+
+ QKmsFramebuffer *m_renderTarget;
+ QKmsFramebuffer *m_displayCanidate;
+ QKmsFramebuffer *m_currentDisplay;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSBUFFERMANAGER_H
diff --git a/src/plugins/platforms/kms/qkmscontext.cpp b/src/plugins/platforms/kms/qkmscontext.cpp
new file mode 100644
index 0000000000..835b6e8e7a
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscontext.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+#include "qkmscontext.h"
+#include "qkmswindow.h"
+
+
+QT_BEGIN_NAMESPACE
+
+QKmsContext::QKmsContext(QKmsDevice *device)
+ : QPlatformGLContext(),
+ m_device(device)
+{
+}
+
+bool QKmsContext::makeCurrent(QPlatformSurface *surface)
+{
+ EGLDisplay display = m_device->eglDisplay();
+ EGLContext context = m_device->eglContext();
+
+ bool ok = eglMakeCurrent(display, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, context);
+ if (!ok)
+ qWarning("QKmsContext::makeCurrent(): eglError: %d, this: %p",
+ eglGetError(), this);
+
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
+ screen->bindFramebuffer();
+ return true;
+}
+
+void QKmsContext::doneCurrent()
+{
+ QPlatformGLContext::doneCurrent();
+ bool ok = eglMakeCurrent(m_device->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ if (!ok)
+ qWarning("QKmsContext::doneCurrent(): eglError: %d, this: %p",
+ eglGetError(), this);
+
+}
+
+void QKmsContext::swapBuffers(QPlatformSurface *surface)
+{
+ //After flush, the current render target should be moved to
+ //latest complete
+ glFlush();
+
+ //Cast context to a window surface and get the screen the context
+ //is on and call swapBuffers on that screen.
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
+ screen->swapBuffers();
+}
+
+void (*QKmsContext::getProcAddress(const QByteArray &procName)) ()
+{
+ return eglGetProcAddress(procName.data());
+}
+
+
+EGLContext QKmsContext::eglContext() const
+{
+ return m_device->eglContext();
+}
+
+QSurfaceFormat QKmsContext::format() const
+{
+ return QSurfaceFormat();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscontext.h b/src/plugins/platforms/kms/qkmscontext.h
new file mode 100644
index 0000000000..25398c5530
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscontext.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSCONTEXT_H
+#define QKMSCONTEXT_H
+
+#include <QtGui/QPlatformGLContext>
+
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsDevice;
+
+class QKmsContext : public QPlatformGLContext
+{
+public:
+ QKmsContext(QKmsDevice *device);
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ void swapBuffers(QPlatformSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ QSurfaceFormat format() const;
+
+ EGLContext eglContext() const;
+
+private:
+
+ QKmsDevice *m_device;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSCONTEXT_H
diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp
new file mode 100644
index 0000000000..91c23b0f1c
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscursor.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmscursor.h"
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+
+QT_BEGIN_NAMESPACE
+
+QKmsCursor::QKmsCursor(QKmsScreen *screen)
+ : QPlatformCursor(screen), m_screen(screen),
+ m_graphicsBufferManager(screen->device()->gbmDevice())
+{
+ gbm_bo *bo = gbm_bo_create(m_graphicsBufferManager, 64, 64,
+ GBM_BO_FORMAT_ARGB8888,
+ GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_RENDERING);
+
+ m_eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR,
+ bo, 0);
+ gbm_bo_destroy(bo);
+ m_cursorImage = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
+}
+
+void QKmsCursor::pointerEvent(const QMouseEvent &event)
+{
+ int status = drmModeMoveCursor(m_screen->device()->fd(),
+ m_screen->crtcId(),
+ event.globalX(),
+ event.globalY());
+ if (status) {
+ qWarning("failed to move cursor: %d", status);
+ }
+}
+
+void QKmsCursor::changeCursor(QCursor *widgetCursor, QWindow *window)
+{
+ Q_UNUSED(window)
+
+ if (widgetCursor->shape() != Qt::BitmapCursor) {
+ m_cursorImage->set(widgetCursor->shape());
+ } else {
+ m_cursorImage->set(widgetCursor->pixmap().toImage(),
+ widgetCursor->hotSpot().x(),
+ widgetCursor->hotSpot().y());
+ }
+
+ if ((m_cursorImage->image()->width() > 64) || (m_cursorImage->image()->width() > 64)) {
+ qWarning("failed to set hardware cursor: larger than 64x64.");
+ return;
+ }
+
+ QImage cursorImage = m_cursorImage->image()->convertToFormat(QImage::Format_RGB32);
+
+ //Load cursor image into EGLImage
+ GLuint cursorTexture;
+ glGenTextures(1, &cursorTexture);
+ glBindTexture(GL_TEXTURE_2D, cursorTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+
+ //TODO: Format may be wrong here, need a color icon to test.
+ if (m_eglImage != EGL_NO_IMAGE_KHR) {
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cursorImage.width(),
+ cursorImage.height(), GL_RGBA,
+ GL_UNSIGNED_BYTE, cursorImage.constBits());
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cursorImage.width(),
+ cursorImage.height(), 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, cursorImage.constBits());
+ }
+
+ //EGLImage needs to contain sprite before calling this:
+ gbm_bo *bufferObject = gbm_bo_create_from_egl_image(m_graphicsBufferManager,
+ m_screen->device()->eglDisplay(),
+ m_eglImage, 64, 64,
+ GBM_BO_USE_CURSOR_64X64);
+ quint32 handle = gbm_bo_get_handle(bufferObject).u32;
+
+ gbm_bo_destroy(bufferObject);
+
+ int status = drmModeSetCursor(m_screen->device()->fd(),
+ m_screen->crtcId(), handle, 64, 64);
+
+ if (status) {
+ qWarning("failed to set cursor: %d", status);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscursor.h b/src/plugins/platforms/kms/qkmscursor.h
new file mode 100644
index 0000000000..96be88e991
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscursor.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSCURSOR_H
+#define QKMSCURSOR_H
+
+#include <QtGui/QPlatformCursor>
+
+#define EGL_EGLEXT_PROTOTYPES 1
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreen;
+class gbm_device;
+
+class QKmsCursor : public QPlatformCursor
+{
+public:
+ QKmsCursor(QKmsScreen *screen);
+
+ void pointerEvent(const QMouseEvent &event);
+ void changeCursor(QCursor *widgetCursor, QWindow *window);
+
+private:
+ QKmsScreen *m_screen;
+ gbm_device *m_graphicsBufferManager;
+ EGLImageKHR m_eglImage;
+ QPlatformCursorImage *m_cursorImage;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSCURSOR_H
diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp
new file mode 100644
index 0000000000..e0fac5611d
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsdevice.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+
+#include "qkmsintegration.h"
+
+#include <QtCore/QSocketNotifier>
+#include <QtCore/private/qcore_unix_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QKmsDevice::QKmsDevice(const QString &path, QKmsIntegration *parent) :
+ QObject(0), m_integration(parent)
+{
+ m_fd = QT_OPEN(path.toAscii().constData(), O_RDWR);
+ if (m_fd < 0) {
+ qWarning("Could not open %s.", path.toAscii().constData());
+ qFatal("No DRM display device");
+ }
+
+ m_graphicsBufferManager = gbm_create_device(m_fd);
+ m_eglDisplay = eglGetDisplay(m_graphicsBufferManager);
+
+ if (m_eglDisplay == EGL_NO_DISPLAY) {
+ qWarning("Could not open EGL display");
+ qFatal("EGL error");
+ }
+
+ EGLint major;
+ EGLint minor;
+ if (!eglInitialize(m_eglDisplay, &major, &minor)) {
+ qWarning("Could not initialize EGL display");
+ qFatal("EGL error");
+ }
+
+ QString extensions = eglQueryString(m_eglDisplay, EGL_EXTENSIONS);
+ if (!extensions.contains(QString::fromLatin1("EGL_KHR_surfaceless_opengl"))) {
+ qFatal("EGL_KHR_surfaceless_opengl extension not available");
+ }
+
+ //Initialize EGLContext
+ static EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ m_eglContext = eglCreateContext(m_eglDisplay, 0, 0, contextAttribs);
+ if (m_eglContext == EGL_NO_CONTEXT) {
+ qWarning("Could not create the EGL context.");
+ eglTerminate(m_eglDisplay);
+ qFatal("EGL error");
+ }
+
+ createScreens();
+
+ QSocketNotifier *notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(handlePageFlipCompleted()));
+}
+
+QKmsDevice::~QKmsDevice()
+{
+ if (m_eglContext != EGL_NO_CONTEXT) {
+ eglDestroyContext(m_eglDisplay, m_eglContext);
+ m_eglContext = EGL_NO_CONTEXT;
+ }
+}
+
+void QKmsDevice::createScreens()
+{
+ drmModeRes *resources = 0;
+ resources = drmModeGetResources(m_fd);
+ if (!resources)
+ qFatal("drmModeGetResources failed");
+
+ //Iterate connectors and create screens on each one active
+ for (int i = 0; i < resources->count_connectors; i++) {
+ drmModeConnector *connector = 0;
+ connector = drmModeGetConnector(m_fd, resources->connectors[i]);
+ if (connector && connector->connection == DRM_MODE_CONNECTED) {
+ m_integration->addScreen(new QKmsScreen(this, connector->connector_id));
+ }
+ drmModeFreeConnector(connector);
+ }
+ drmModeFreeResources(resources);
+}
+
+void QKmsDevice::handlePageFlipCompleted()
+{
+ //qDebug() << "Display signal recieved";
+ drmEventContext eventContext;
+
+ memset(&eventContext, 0, sizeof eventContext);
+ eventContext.version = DRM_EVENT_CONTEXT_VERSION;
+ eventContext.page_flip_handler = QKmsDevice::pageFlipHandler;
+ drmHandleEvent(m_fd, &eventContext);
+
+}
+
+void QKmsDevice::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
+{
+ Q_UNUSED(fd)
+ Q_UNUSED(frame)
+ Q_UNUSED(sec)
+ Q_UNUSED(usec)
+ static unsigned int previousTime = 0;
+
+ unsigned int currentTime = sec * 1000000 + usec;
+ unsigned int refreshTime = 0;
+// qDebug() << "fd: " << fd << " frame: " << frame << " sec: "
+// << sec << " usec: " << usec << " data: " << data
+// << "msecs" << sec * 1000 + usec / 1000;
+ QKmsScreen *screen = static_cast<QKmsScreen *>(data);
+
+ if (previousTime == 0)
+ refreshTime = 16000;
+ else
+ refreshTime = currentTime - previousTime;
+
+ screen->setFlipReady(refreshTime);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsdevice.h b/src/plugins/platforms/kms/qkmsdevice.h
new file mode 100644
index 0000000000..4868a72ede
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsdevice.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSDEVICE_H
+#define QKMSDEVICE_H
+
+extern "C" {
+#include <gbm.h>
+}
+#include <EGL/egl.h>
+
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class gbm_device;
+class QKmsIntegration;
+
+class QKmsDevice : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QKmsDevice(const QString &path, QKmsIntegration *parent);
+ ~QKmsDevice();
+
+ EGLDisplay eglDisplay() { return m_eglDisplay; }
+ gbm_device *gbmDevice() { return m_graphicsBufferManager; }
+ EGLContext eglContext() { return m_eglContext; }
+ int fd() const { return m_fd; }
+
+ static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec,
+ unsigned int usec, void *data);
+
+public slots:
+ void handlePageFlipCompleted();
+private:
+ void createScreens();
+
+ QKmsIntegration *m_integration;
+
+ EGLDisplay m_eglDisplay;
+ EGLContext m_eglContext;
+ gbm_device *m_graphicsBufferManager;
+ int m_fd;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSDEVICE_H
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
new file mode 100644
index 0000000000..18e305d633
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsintegration.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsintegration.h"
+#include "qkmsdevice.h"
+#include "qkmsscreen.h"
+#include "qkmswindow.h"
+#include "qkmsbackingstore.h"
+#include "qkmscontext.h"
+
+#include <QtPlatformSupport/private/qgenericunixprintersupport_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QGuiGLContext>
+#include <QtGui/QScreen>
+
+QT_BEGIN_NAMESPACE
+
+QKmsIntegration::QKmsIntegration()
+ : QPlatformIntegration(),
+ m_fontDatabase(new QGenericUnixFontDatabase()),
+ m_printerSupport(new QGenericUnixPrinterSupport()),
+ m_eventDispatcher(createUnixEventDispatcher())
+{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
+ setenv("EGL_PLATFORM", "drm",1);
+ QStringList drmDevices = findDrmDevices();
+ foreach (QString path, drmDevices) {
+ m_devices.append(new QKmsDevice(path, this));
+ }
+}
+
+QKmsIntegration::~QKmsIntegration()
+{
+ foreach (QKmsDevice *device, m_devices) {
+ delete device;
+ }
+ foreach (QPlatformScreen *screen, m_screens) {
+ delete screen;
+ }
+ delete m_printerSupport;
+ delete m_fontDatabase;
+}
+
+bool QKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformGLContext *QKmsIntegration::createPlatformGLContext(QGuiGLContext *context) const
+{
+ QKmsScreen *screen = static_cast<QKmsScreen *>(context->screen()->handle());
+ return new QKmsContext(screen->device());
+}
+
+QPlatformWindow *QKmsIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QKmsWindow(window);
+}
+
+QPlatformBackingStore *QKmsIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QKmsBackingStore(window);
+}
+
+QPlatformFontDatabase *QKmsIntegration::fontDatabase() const
+{
+ return m_fontDatabase;
+}
+
+QStringList QKmsIntegration::findDrmDevices()
+{
+ //Return a list addresses of DRM supported devices
+ //Hardcoded now, but could use udev to return a list
+ //of multiple devices.
+ return QStringList(QString::fromLatin1("/dev/dri/card0"));
+}
+
+void QKmsIntegration::addScreen(QKmsScreen *screen)
+{
+ m_screens.append(screen);
+ screenAdded(screen);
+}
+
+QAbstractEventDispatcher *QKmsIntegration::guiThreadEventDispatcher() const
+{
+ return m_eventDispatcher;
+}
+
+QPlatformPrinterSupport *QKmsIntegration::printerSupport() const
+{
+ return m_printerSupport;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
new file mode 100644
index 0000000000..bf84e1b33b
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsintegration.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMINTEGRATION_KMS_H
+#define QPLATFORMINTEGRATION_KMS_H
+
+#include <QtGui/QPlatformIntegration>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreen;
+class QKmsDevice;
+
+class QKmsIntegration : public QPlatformIntegration
+{
+public:
+ QKmsIntegration();
+ ~QKmsIntegration();
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+
+ QPlatformGLContext *createPlatformGLContext(QGuiGLContext *context) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+
+ QPlatformFontDatabase *fontDatabase() const;
+ QPlatformPrinterSupport *printerSupport() const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
+ void addScreen(QKmsScreen *screen);
+
+private:
+ QStringList findDrmDevices();
+
+ QList<QPlatformScreen *> m_screens;
+ QList<QKmsDevice *> m_devices;
+ QPlatformFontDatabase *m_fontDatabase;
+ QPlatformPrinterSupport *m_printerSupport;
+ QAbstractEventDispatcher *m_eventDispatcher;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp
new file mode 100644
index 0000000000..0cd1530930
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsscreen.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmscursor.h"
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+#include "qkmscontext.h"
+#include "qkmsbuffermanager.h"
+
+QT_BEGIN_NAMESPACE
+
+//Fallback mode (taken from Wayland DRM demo compositor)
+static drmModeModeInfo builtin_1024x768 = {
+ 63500, //clock
+ 1024, 1072, 1176, 1328, 0,
+ 768, 771, 775, 798, 0,
+ 59920,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
+ 0,
+ "1024x768"
+};
+
+QKmsScreen::QKmsScreen(QKmsDevice *device, int connectorId)
+ : m_device(device),
+ m_flipReady(true),
+ m_connectorId(connectorId),
+ m_depth(32),
+ m_format(QImage::Format_Invalid),
+ m_bufferManager(this),
+ m_refreshTime(16000)
+{
+ m_cursor = new QKmsCursor(this);
+ initializeScreenMode();
+}
+
+QKmsScreen::~QKmsScreen()
+{
+ delete m_cursor;
+}
+
+QRect QKmsScreen::geometry() const
+{
+ return m_geometry;
+}
+
+int QKmsScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QKmsScreen::format() const
+{
+ return m_format;
+}
+
+QSize QKmsScreen::physicalSize() const
+{
+ return m_physicalSize;
+}
+
+GLuint QKmsScreen::framebufferObject() const
+{
+ return m_bufferManager.framebufferObject();
+}
+
+void QKmsScreen::initializeScreenMode()
+{
+ //Determine optimal mode for screen
+ drmModeRes *resources = drmModeGetResources(m_device->fd());
+ if (!resources)
+ qFatal("drmModeGetResources failed");
+
+ drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId);
+ drmModeModeInfo *mode = 0;
+ if (connector->count_modes > 0)
+ mode = &connector->modes[0];
+ else
+ mode = &builtin_1024x768;
+
+ drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
+ if (encoder == 0)
+ qFatal("No encoder for connector.");
+
+ int i;
+ for (i = 0; i < resources->count_crtcs; i++) {
+ if (encoder->possible_crtcs & (1 << i))
+ break;
+ }
+ if (i == resources->count_crtcs)
+ qFatal("No usable crtc for encoder.");
+
+ m_crtcId = resources->crtcs[i];
+ m_mode = *mode;
+ m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay);
+ m_depth = 32;
+ m_format = QImage::Format_RGB32;
+ m_physicalSize = QSize(connector->mmWidth, connector->mmHeight);
+
+ //Setup three buffers for current mode
+ m_bufferManager.setupBuffersForMode(m_mode, 3);
+
+ //Set the Mode of the screen.
+ int ret = drmModeSetCrtc(m_device->fd(), m_crtcId, m_bufferManager.displayFramebufferId(),
+ 0, 0, &m_connectorId, 1, &m_mode);
+ if (ret)
+ qFatal("failed to set mode");
+
+ //Cleanup
+ drmModeFreeEncoder(encoder);
+ drmModeFreeConnector(connector);
+ drmModeFreeResources(resources);
+}
+
+void QKmsScreen::bindFramebuffer()
+{
+ if (m_bufferManager.framebufferObject()) {
+ glBindFramebuffer(GL_FRAMEBUFFER, m_bufferManager.framebufferObject());
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ m_bufferManager.renderTargetBuffer());
+ }
+}
+
+void QKmsScreen::swapBuffers()
+{
+ waitForPageFlipComplete();
+
+ if ( m_flipReady )
+ performPageFlip();
+ //TODO: Do something with return value here
+ m_bufferManager.nextBuffer();
+ //qDebug() << "swapBuffers now rendering to " << m_bufferManager.renderTargetBuffer();
+ bindFramebuffer();
+}
+
+void QKmsScreen::performPageFlip()
+{
+ quint32 displayFramebufferId = m_bufferManager.displayFramebufferId();
+ //qDebug() << "Flipping to framebuffer: " << displayFramebufferId;
+
+ int pageFlipStatus = drmModePageFlip(m_device->fd(), m_crtcId,
+ displayFramebufferId,
+ DRM_MODE_PAGE_FLIP_EVENT, this);
+ if (pageFlipStatus)
+ qWarning("Pageflip status: %d", pageFlipStatus);
+
+ m_flipReady = false;
+}
+
+void QKmsScreen::setFlipReady(unsigned int time)
+{
+ m_flipReady = true;
+ m_refreshTime = time;
+ performPageFlip();
+}
+
+QKmsDevice * QKmsScreen::device() const
+{
+ return m_device;
+}
+
+void QKmsScreen::waitForPageFlipComplete()
+{
+ //Check manually if there is something to be read on the device
+ //as there are senarios where the signal is not received (starvation)
+ fd_set fdSet;
+ timeval timeValue;
+ int returnValue;
+
+ FD_ZERO(&fdSet);
+ FD_SET(m_device->fd(), &fdSet);
+ timeValue.tv_sec = 0;
+ timeValue.tv_usec = m_refreshTime;
+
+ returnValue = select(1, &fdSet, 0, 0, &timeValue);
+
+ if (returnValue) {
+ m_device->handlePageFlipCompleted();
+ }
+
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h
new file mode 100644
index 0000000000..5c8b5ca4f5
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsscreen.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSSCREEN_H
+#define QKMSSCREEN_H
+
+#include <QtGui/QPlatformScreen>
+#include "qkmsbuffermanager.h"
+
+QT_BEGIN_NAMESPACE
+
+class QKmsCursor;
+class QKmsDevice;
+class QKmsContext;
+
+class QKmsScreen : public QPlatformScreen
+{
+public:
+ QKmsScreen(QKmsDevice *device, int connectorId);
+ ~QKmsScreen();
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSize physicalSize() const;
+
+ GLuint framebufferObject() const;
+ quint32 crtcId() const { return m_crtcId; }
+ QKmsDevice *device() const;
+
+ //Called by context for each screen
+ void bindFramebuffer();
+ void swapBuffers();
+ void setFlipReady(unsigned int time);
+
+private:
+ void performPageFlip();
+ void initializeScreenMode();
+ void waitForPageFlipComplete();
+
+ QKmsDevice *m_device;
+ bool m_flipReady;
+ quint32 m_connectorId;
+
+ quint32 m_crtcId;
+ drmModeModeInfo m_mode;
+ QRect m_geometry;
+ QSize m_physicalSize;
+ int m_depth;
+ QImage::Format m_format;
+
+ QKmsCursor *m_cursor;
+ QKmsBufferManager m_bufferManager;
+ unsigned int m_refreshTime;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSSCREEN_H
diff --git a/src/plugins/platforms/kms/qkmswindow.cpp b/src/plugins/platforms/kms/qkmswindow.cpp
new file mode 100644
index 0000000000..63271c4ef5
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmswindow.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmswindow.h"
+#include "qkmsscreen.h"
+
+#include <QtGui/QWindowSystemInterface>
+QT_BEGIN_NAMESPACE
+
+QKmsWindow::QKmsWindow(QWindow *window)
+ : QPlatformWindow(window)
+{
+ m_screen = QPlatformScreen::platformScreenForWindow(window);
+}
+
+void QKmsWindow::setGeometry(const QRect &rect)
+{
+ Q_UNUSED(rect)
+ //All Windows must be fullscreen
+ QRect fullscreenRect = m_screen->availableGeometry();
+ QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
+
+ QPlatformWindow::setGeometry(fullscreenRect);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmswindow.h b/src/plugins/platforms/kms/qkmswindow.h
new file mode 100644
index 0000000000..789d42e6f8
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmswindow.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSWINDOW_H
+#define QKMSWINDOW_H
+
+#include <QtGui/QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsWindow : public QPlatformWindow
+{
+public:
+ QKmsWindow(QWindow *window);
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QPlatformScreen *m_screen;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSWINDOW_H