diff --git a/src/plugins/platforms/eglkms/eglkms.pro b/src/plugins/platforms/eglkms/eglkms.pro new file mode 100644 index 0000000..d3eb0eb --- /dev/null +++ b/src/plugins/platforms/eglkms/eglkms.pro @@ -0,0 +1,28 @@ +TARGET = qeglkms +TEMPLATE = lib +CONFIG += plugin link_pkgconfig +PKGCONFIG += libdrm egl + +QT += opengl + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms + +#DEFINES += QEGL_EXTRA_DEBUG + +SOURCES = main.cpp \ + qeglkmsintegration.cpp \ + qeglkmscontext.cpp \ + qeglkmswindow.cpp \ + qeglkmswindowsurface.cpp \ + qeglkmsscreen.cpp + +HEADERS = qeglkmsintegration.h \ + qeglkmscontext.h \ + qeglkmswindow.h \ + qeglkmswindowsurface.h \ + qeglkmsscreen.h + +include(../fontdatabases/genericunix/genericunix.pri) + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target diff --git a/src/plugins/platforms/eglkms/main.cpp b/src/plugins/platforms/eglkms/main.cpp new file mode 100644 index 0000000..6e13c4e --- /dev/null +++ b/src/plugins/platforms/eglkms/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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "qeglkmsintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglIntegrationPlugin : public QPlatformIntegrationPlugin +{ +public: + QStringList keys() const; + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QStringList QEglIntegrationPlugin::keys() const +{ + QStringList list; + list << "EglKMS"; + return list; +} + +QPlatformIntegration* QEglIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "eglkms") + return new QEglKMSIntegration; + + return 0; +} + +Q_EXPORT_PLUGIN2(eglintegration, QEglIntegrationPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglkms/qeglkmscontext.cpp b/src/plugins/platforms/eglkms/qeglkmscontext.cpp new file mode 100644 index 0000000..ac6e94a --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmscontext.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglkmscontext.h" + +#include + +extern "C" { +#include +} + +QEGLKMSContext::QEGLKMSContext(EGLDisplay display, int fd, + EGLint contextAttrs[], EGLenum eglApi) + : QPlatformGLContext() + , m_eglDisplay(display) + , m_eglApi(eglApi) + , m_fd(fd) + , m_fbo(0) +{ + eglBindAPI(m_eglApi); + m_eglContext = eglCreateContext(m_eglDisplay, 0, 0, contextAttrs); + if (m_eglContext == EGL_NO_CONTEXT) { + qWarning("Could not create the egl context\n"); + eglTerminate(m_eglDisplay); + qFatal("EGL error"); + } + + setDefaultSharedContext(this); +} + +QEGLKMSContext::~QEGLKMSContext() +{ + if (m_eglContext != EGL_NO_CONTEXT) { + eglDestroyContext(m_eglDisplay, m_eglContext); + m_eglContext = EGL_NO_CONTEXT; + } +} + +void QEGLKMSContext::makeCurrent() +{ + QPlatformGLContext::makeCurrent(); + bool ok = eglMakeCurrent(m_eglDisplay, + EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext); + if (!ok) + qWarning("QEGLKMSContext::makeCurrent: eglError: %d, this: %p \n", + eglGetError(), this); + + if (m_fbo) { + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, + m_rbo[m_current]); + } + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + qWarning("incomplete framebuffer\n"); +} + +void QEGLKMSContext::doneCurrent() +{ + QPlatformGLContext::doneCurrent(); + bool ok = eglMakeCurrent(m_eglDisplay, + EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (!ok) + qWarning("QEGLKMSContext::doneCurrent(): eglError: %d, this: %p \n", + eglGetError(), this); +} + +void QEGLKMSContext::swapBuffers() +{ + glFlush(); + + drmModePageFlip(m_fd, m_crtcId, + m_fbId[m_current], + 0, NULL); // No event yet + + m_current ^= 1; + + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, + m_rbo[m_current]); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + qWarning("framebuffer incomplete\n"); +} + +void* QEGLKMSContext::getProcAddress(const QString& procName) +{ + return (void *)eglGetProcAddress(qPrintable(procName)); +} + +void QEGLKMSContext::makeDefaultSharedContext() +{ + setDefaultSharedContext(this); +} + +QPlatformWindowFormat QEGLKMSContext::platformWindowFormat() const +{ + QPlatformWindowFormat format; + + format.setRedBufferSize(8); + format.setGreenBufferSize(8); + format.setBlueBufferSize(8); + format.setAlphaBufferSize(8); + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + format.setSamples(1); + format.setDirectRendering(true); + format.setRgba(true); + format.setStereo(false); + format.setAccumBufferSize(0); + + return format; +} + +EGLContext QEGLKMSContext::eglContext() const +{ + return m_eglContext; +} diff --git a/src/plugins/platforms/eglkms/qeglkmscontext.h b/src/plugins/platforms/eglkms/qeglkmscontext.h new file mode 100644 index 0000000..9b1ae1b --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmscontext.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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLKMSCONTEXT_H +#define QEGLKMSCONTEXT_H + +#include + +#define EGL_EGLEXT_PROTOTYPES 1 +#define GL_GLEXT_PROTOTYPES 1 + +#include +#include +#include +#include + +class QEGLKMSContext : public QPlatformGLContext +{ +public: + QEGLKMSContext(EGLDisplay display, int fd, + EGLint contextAttrs[], EGLenum eglApi); + ~QEGLKMSContext(); + + void makeCurrent(); + void doneCurrent(); + void swapBuffers(); + void* getProcAddress(const QString& procName); + + void makeDefaultSharedContext(); + + QPlatformWindowFormat platformWindowFormat() const; + + EGLContext eglContext() const; + + void setStuff(int crtcId, GLuint fbo, uint32_t fbId[2], GLuint rbo[2]) { + m_crtcId = crtcId; + m_fbo = fbo; + m_fbId[0] = fbId[0]; + m_fbId[1] = fbId[1]; + m_rbo[0] = rbo[0]; + m_rbo[1] = rbo[1]; + m_current = 0; + } + +private: + EGLContext m_eglContext; + EGLDisplay m_eglDisplay; + EGLenum m_eglApi; + + int m_fd; + int m_crtcId; + uint32_t m_fbId[2]; + GLuint m_rbo[2]; + GLuint m_fbo; + int m_current; + +}; + +#endif //QEGLKMSCONTEXT_H diff --git a/src/plugins/platforms/eglkms/qeglkmsintegration.cpp b/src/plugins/platforms/eglkms/qeglkmsintegration.cpp new file mode 100644 index 0000000..ceeff6d --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmsintegration.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgenericunixfontdatabase.h" + +#include "qeglkmsintegration.h" + +#include "qeglkmswindow.h" +#include "qeglkmswindowsurface.h" + +#include +#include +#include + +#include +#include + +#include + +extern "C" { +EGLAPI EGLDisplay EGLAPIENTRY eglGetDRMDisplayMESA(int fd); +} + +QT_BEGIN_NAMESPACE + +QEglKMSIntegration::QEglKMSIntegration() + : mFontDb(new QGenericUnixFontDatabase()) +{ + EGLint major, minor; + const char *filename = "/dev/dri/card0"; + const char *extensions; + + m_fd = open(filename, O_RDWR); + if (m_fd < 0) { + qWarning("Could not open %s, skipping\n", filename); + qFatal("EGL error"); + } + + m_dpy = eglGetDRMDisplayMESA(m_fd); + if (m_dpy == EGL_NO_DISPLAY) { + qWarning("Could not open egl display\n"); + qFatal("EGL error"); + } + qWarning("Opened EGL display %p\n", m_dpy); + + if (!eglInitialize(m_dpy, &major, &minor)) { + qWarning("Could not initialize egl display\n"); + qFatal("EGL error"); + } + + extensions = eglQueryString(m_dpy, EGL_EXTENSIONS); + if (!strstr(extensions, "EGL_KHR_surfaceless_opengl")) + qFatal("EGL_KHR_surfaceless_opengl not available\n"); + + qWarning("Initialized display %d %d\n", major, minor); + + int swapInterval = 1; + QByteArray swapIntervalString = qgetenv("QT_QPA_EGLKMS_SWAPINTERVAL"); + if (!swapIntervalString.isEmpty()) { + bool ok; + swapInterval = swapIntervalString.toInt(&ok); + if (!ok) + swapInterval = 1; + } + eglSwapInterval(m_dpy, swapInterval); + + drmModeConnector *connector; + drmModeRes *resources; + + resources = drmModeGetResources(m_fd); + if (!resources) + qFatal("drmModeGetResources failed\n"); + + for (int i = 0; i < resources->count_connectors; i++) { + connector = drmModeGetConnector(m_fd, resources->connectors[i]); + if (connector && connector->connection == DRM_MODE_CONNECTED) { + qWarning("Using connector %d\n", connector->connector_id); + + m_primaryScreen = new QEglKMSScreen(m_dpy, m_fd, + connector->connector_id); + mScreens.append(m_primaryScreen); + } + drmModeFreeConnector(connector); + } + + drmModeFreeResources(resources); +} + +bool QEglKMSIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + switch (cap) { + case ThreadedPixmaps: return true; + default: return QPlatformIntegration::hasCapability(cap); + } +} + +QPixmapData *QEglKMSIntegration::createPixmapData(QPixmapData::PixelType type) const +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglIntegration::createPixmapData %d\n", type); +#endif + return new QGLPixmapData(type); +} + +QPlatformWindow *QEglKMSIntegration::createPlatformWindow(QWidget *widget, WId winId) const +{ + Q_UNUSED(winId); +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglIntegration::createPlatformWindow %p\n",widget); +#endif + return new QEglKMSWindow(widget, m_primaryScreen); +} + + +QWindowSurface *QEglKMSIntegration::createWindowSurface(QWidget *widget, WId winId) const +{ + Q_UNUSED(winId); + +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglIntegration::createWindowSurface %p\n",widget); +#endif + return new QEglKMSWindowSurface(m_primaryScreen,widget); +} + +QPlatformFontDatabase *QEglKMSIntegration::fontDatabase() const +{ + return mFontDb; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglkms/qeglkmsintegration.h b/src/plugins/platforms/eglkms/qeglkmsintegration.h new file mode 100644 index 0000000..eeacc4b --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmsintegration.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EGLKMSINTEGRATION_H +#define EGLKMSINTEGRATION_H + +#include "qeglkmsscreen.h" + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QEglKMSIntegration : public QPlatformIntegration +{ +public: + QEglKMSIntegration(); + + bool hasCapability(QPlatformIntegration::Capability cap) const; + QPixmapData *createPixmapData(QPixmapData::PixelType type) const; + QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const; + QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const; + + QList screens() const { return mScreens; } + + QPlatformFontDatabase *fontDatabase() const; + +private: + QPlatformFontDatabase *mFontDb; + QList mScreens; + QEglKMSScreen *m_primaryScreen; + EGLDisplay m_dpy; + int m_fd; +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/plugins/platforms/eglkms/qeglkmsscreen.cpp b/src/plugins/platforms/eglkms/qeglkmsscreen.cpp new file mode 100644 index 0000000..05409d8 --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmsscreen.cpp @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglkmsscreen.h" +#include "qeglkmscontext.h" + +QT_BEGIN_NAMESPACE + +// #define QEGL_EXTRA_DEBUG + +QEglKMSScreen::QEglKMSScreen(EGLDisplay dpy, int fd, int connectorId) + : m_connectorId(connectorId) + , m_depth(32) + , m_fd(fd) + , m_format(QImage::Format_Invalid) + , m_platformContext(0) + , m_dpy(dpy) + , m_surface(0) +{ +} + +void QEglKMSScreen::createAndSetPlatformContext() const { + const_cast(this)->createAndSetPlatformContext(); +} + + +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" +}; + +void QEglKMSScreen::createAndSetPlatformContext() +{ + static EGLint contextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + m_platformContext = + new QEGLKMSContext(m_dpy, m_fd, contextAttribs, EGL_OPENGL_ES_API); + + m_platformContext->makeCurrent(); + + drmModeRes *resources; + drmModeEncoder *encoder; + drmModeModeInfo *mode; + drmModeConnector *connector; + int i, ret; + EGLint handle, stride, attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA, + EGL_NONE + }; + + resources = drmModeGetResources(m_fd); + if (!resources) + qFatal("drmModeGetResources failed\n"); + + connector = drmModeGetConnector(m_fd, m_connectorId); + + if (connector->count_modes > 0) + mode = &connector->modes[0]; + else + mode = &builtin_1024x768; + + encoder = drmModeGetEncoder(m_fd, connector->encoders[0]); + if (encoder == NULL) + qFatal("No encoder for connector.\n"); + + 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.\n"); + + 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; + + drmModeFreeEncoder(encoder); + + qWarning("using connector %d, mode %dx%d\n", + connector->connector_id, m_geometry.width(), m_geometry.height()); + + glGenFramebuffers(1, &m_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + glGenRenderbuffers(2, m_rbo); + for (i = 0; i < 2; i++) { + glBindRenderbuffer(GL_RENDERBUFFER, m_rbo[i]); + + attribs[1] = m_mode.hdisplay; + attribs[3] = m_mode.vdisplay; + m_image[i] = eglCreateDRMImageMESA(m_dpy, attribs); + glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, m_image[i]); + eglExportDRMImageMESA(m_dpy, m_image[i], NULL, &handle, &stride); + + ret = drmModeAddFB(m_fd, m_geometry.width(), m_geometry.height(), + 32, 32, stride, handle, &m_fbId[i]); + if (ret) + qFatal("failed to add fb %d: %m\n", i); + } + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, + m_rbo[0]); + ret = drmModeSetCrtc(m_fd, m_crtcId, m_fbId[1], + 0, 0, &m_connectorId, 1, &m_mode); + if (ret) + qFatal("failed to set mode: %m\n"); + + m_platformContext->setStuff(m_crtcId, m_fbo, m_fbId, m_rbo); + + drmModeFreeResources(resources); +} + +QRect QEglKMSScreen::geometry() const +{ + if (m_geometry.isNull()) + createAndSetPlatformContext(); + + return m_geometry; +} + +int QEglKMSScreen::depth() const +{ + return m_depth; +} + +QImage::Format QEglKMSScreen::format() const +{ + if (m_format == QImage::Format_Invalid) + createAndSetPlatformContext(); + return m_format; +} +QPlatformGLContext *QEglKMSScreen::platformContext() const +{ + if (!m_platformContext) { + QEglKMSScreen *that = const_cast(this); + that->createAndSetPlatformContext(); + } + return m_platformContext; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglkms/qeglkmsscreen.h b/src/plugins/platforms/eglkms/qeglkmsscreen.h new file mode 100644 index 0000000..9c0518c --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmsscreen.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLKMSSCREEN_H +#define QEGLKMSSCREEN_H + +#include + +#define EGL_EGLEXT_PROTOTYPES 1 +#define GL_GLEXT_PROTOTYPES 1 + +#include +#include +#include +#include + +extern "C" { +#include +} + +QT_BEGIN_NAMESPACE + +class QEGLKMSContext; + +class QEglKMSScreen : public QPlatformScreen +{ +public: + QEglKMSScreen(EGLDisplay dpy, int fd, int connectorId); + ~QEglKMSScreen() {} + + QRect geometry() const; + int depth() const; + QImage::Format format() const; + + QPlatformGLContext *platformContext() const; + + GLuint getFBO() const { return m_fbo; }; + +private: + void createAndSetPlatformContext() const; + void createAndSetPlatformContext(); + + QRect m_geometry; + uint32_t m_connectorId; + int m_depth; + int m_fd; + uint32_t m_crtcId; + drmModeModeInfo m_mode; + + QImage::Format m_format; + QEGLKMSContext *m_platformContext; + EGLDisplay m_dpy; + EGLSurface m_surface; + GLuint m_fbo, m_rbo[2]; + uint32_t m_fbId[2]; + EGLImageKHR m_image[2]; +}; + +QT_END_NAMESPACE +#endif // QEGLKMSSCREEN_H diff --git a/src/plugins/platforms/eglkms/qeglkmswindow.cpp b/src/plugins/platforms/eglkms/qeglkmswindow.cpp new file mode 100644 index 0000000..2900e9f --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmswindow.cpp @@ -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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglkmswindow.h" + +#include + +QT_BEGIN_NAMESPACE + +QEglKMSWindow::QEglKMSWindow(QWidget *w, QEglKMSScreen *screen) + : QPlatformWindow(w), m_screen(screen) +{ + static int serialNo = 0; + m_winid = ++serialNo; +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglWindow %p: %p %p 0x%x\n", this, w, screen, uint(m_winid)); +#endif +} + + +void QEglKMSWindow::setGeometry(const QRect &) +{ + // We only support full-screen windows + QRect rect(m_screen->availableGeometry()); + QWindowSystemInterface::handleGeometryChange(this->widget(), rect); + + // Since toplevels are fullscreen, propegate the screen size back to the widget + widget()->setGeometry(rect); + + QPlatformWindow::setGeometry(rect); +} + +WId QEglKMSWindow::winId() const +{ + return m_winid; +} + + + +QPlatformGLContext *QEglKMSWindow::glContext() const +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglWindow::glContext %p\n", m_screen->platformContext()); +#endif + Q_ASSERT(m_screen); + return m_screen->platformContext(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglkms/qeglkmswindow.h b/src/plugins/platforms/eglkms/qeglkmswindow.h new file mode 100644 index 0000000..4ef6bed --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmswindow.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLKMSWINDOW_H +#define QEGLKMSWINDOW_H + +#include "qeglkmsintegration.h" +#include "qeglkmsscreen.h" + + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class QEglKMSWindow : public QPlatformWindow +{ +public: + QEglKMSWindow(QWidget *w, QEglKMSScreen *screen); + + void setGeometry(const QRect &); + WId winId() const; + + QPlatformGLContext *glContext() const; + +private: + QEglKMSScreen *m_screen; + WId m_winid; +}; +QT_END_NAMESPACE +#endif // QEGLKMSWINDOW_H diff --git a/src/plugins/platforms/eglkms/qeglkmswindowsurface.cpp b/src/plugins/platforms/eglkms/qeglkmswindowsurface.cpp new file mode 100644 index 0000000..878d4ba --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmswindowsurface.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglkmswindowsurface.h" + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QEglKMSPaintDevice : public QGLPaintDevice +{ +public: + QEglKMSPaintDevice(QEglKMSScreen *screen, QWidget *widget) + :QGLPaintDevice(), m_screen(screen) + { + Q_UNUSED(widget); + m_thisFBO = screen->getFBO(); + #ifdef QEGL_EXTRA_DEBUG + qWarning("QEglPaintDevice %p, %p, %p",this, screen, widget); + #endif + } + + QSize size() const { return m_screen->geometry().size(); } + QGLContext* context() const { return QGLContext::fromPlatformGLContext(m_screen->platformContext());} + + QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } + + void beginPaint(){ + QGLPaintDevice::beginPaint(); + } + + virtual bool isFlipped() const { return true; } + +private: + QEglKMSScreen *m_screen; + QGLContext *m_context; +}; + + +QEglKMSWindowSurface::QEglKMSWindowSurface( QEglKMSScreen *screen, QWidget *window ) + :QWindowSurface(window) +{ +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglWindowSurface %p, %p", window, screen); +#endif + m_paintDevice = new QEglKMSPaintDevice(screen,window); +} + +void QEglKMSWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(widget); + Q_UNUSED(region); + Q_UNUSED(offset); +#ifdef QEGL_EXTRA_DEBUG + qWarning("QEglWindowSurface::flush %p",widget); +#endif + widget->platformWindow()->glContext()->swapBuffers(); +} + +void QEglKMSWindowSurface::resize(const QSize &size) +{ + Q_UNUSED(size); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglkms/qeglkmswindowsurface.h b/src/plugins/platforms/eglkms/qeglkmswindowsurface.h new file mode 100644 index 0000000..6c53992 --- /dev/null +++ b/src/plugins/platforms/eglkms/qeglkmswindowsurface.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLKMSWINDOWSURFACE_H +#define QEGLKMSWINDOWSURFACE_H + +#include "qeglkmsintegration.h" +#include "qeglkmswindow.h" + +#include + +QT_BEGIN_NAMESPACE + +class QEglKMSWindowSurface : public QWindowSurface +{ +public: + QEglKMSWindowSurface(QEglKMSScreen *screen, QWidget *window); + ~QEglKMSWindowSurface() {} + + QPaintDevice *paintDevice() { return m_paintDevice; } + void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size); +private: + QPaintDevice *m_paintDevice; +}; + +QT_END_NAMESPACE + +#endif // QEGLKMSWINDOWSURFACE_H