Initial support for Qt using Kernel Mode-setting (KMS)

This platform plugin supports fullscreen OpenGLES2 windows on devices
that support Kernel Mode-setting.

Change-Id: I7d4077319654c13851f0ff7ec0228b7b13936382
Reviewed-on: http://codereview.qt.nokia.com/2516
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
This commit is contained in:
Andy Nichols 2011-08-02 15:07:50 +02:00 committed by Jørgen Lind
parent 4b126d321e
commit 9a652ed802
18 changed files with 1864 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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