1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
4 ** Copyright (C) 2016 The Qt Company Ltd.
5 ** Copyright (C) 2016 Pelagicore AG
6 ** Contact: https://www.qt.io/licensing/
7 **
8 ** This file is part of the plugins of the Qt Toolkit.
9 **
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** Commercial License Usage
12 ** Licensees holding valid commercial Qt licenses may use this file in
13 ** accordance with the commercial license agreement provided with the
14 ** Software or, alternatively, in accordance with the terms contained in
15 ** a written agreement between you and The Qt Company. For licensing terms
16 ** and conditions see https://www.qt.io/terms-conditions. For further
17 ** information use the contact form at https://www.qt.io/contact-us.
18 **
19 ** GNU Lesser General Public License Usage
20 ** Alternatively, this file may be used under the terms of the GNU Lesser
21 ** General Public License version 3 as published by the Free Software
22 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
23 ** packaging of this file. Please review the following information to
24 ** ensure the GNU Lesser General Public License version 3 requirements
25 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26 **
27 ** GNU General Public License Usage
28 ** Alternatively, this file may be used under the terms of the GNU
29 ** General Public License version 2.0 or (at your option) the GNU General
30 ** Public license version 3 or any later version approved by the KDE Free
31 ** Qt Foundation. The licenses are as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33 ** included in the packaging of this file. Please review the following
34 ** information to ensure the GNU General Public License requirements will
35 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36 ** https://www.gnu.org/licenses/gpl-3.0.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qeglfskmsintegration.h"
43 #include "qeglfskmsscreen.h"
44 
45 #include <QtKmsSupport/private/qkmsdevice_p.h>
46 
47 #include <QtGui/qpa/qplatformwindow.h>
48 #include <QtGui/QScreen>
49 
50 #include <xf86drm.h>
51 #include <xf86drmMode.h>
52 
53 QT_BEGIN_NAMESPACE
54 
55 Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms")
56 
QEglFSKmsIntegration()57 QEglFSKmsIntegration::QEglFSKmsIntegration()
58     : m_device(nullptr),
59       m_screenConfig(new QKmsScreenConfig)
60 {
61 }
62 
~QEglFSKmsIntegration()63 QEglFSKmsIntegration::~QEglFSKmsIntegration()
64 {
65     delete m_screenConfig;
66 }
67 
platformInit()68 void QEglFSKmsIntegration::platformInit()
69 {
70     qCDebug(qLcEglfsKmsDebug, "platformInit: Opening DRM device");
71     m_device = createDevice();
72     if (Q_UNLIKELY(!m_device->open()))
73         qFatal("Could not open DRM device");
74 }
75 
platformDestroy()76 void QEglFSKmsIntegration::platformDestroy()
77 {
78     qCDebug(qLcEglfsKmsDebug, "platformDestroy: Closing DRM device");
79     m_device->close();
80     delete m_device;
81     m_device = nullptr;
82 }
83 
platformDisplay() const84 EGLNativeDisplayType QEglFSKmsIntegration::platformDisplay() const
85 {
86     Q_ASSERT(m_device);
87     return (EGLNativeDisplayType) m_device->nativeDisplay();
88 }
89 
usesDefaultScreen()90 bool QEglFSKmsIntegration::usesDefaultScreen()
91 {
92     return false;
93 }
94 
screenInit()95 void QEglFSKmsIntegration::screenInit()
96 {
97     m_device->createScreens();
98 }
99 
surfaceFormatFor(const QSurfaceFormat & inputFormat) const100 QSurfaceFormat QEglFSKmsIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
101 {
102     QSurfaceFormat format(inputFormat);
103     format.setRenderableType(QSurfaceFormat::OpenGLES);
104     format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
105     format.setRedBufferSize(8);
106     format.setGreenBufferSize(8);
107     format.setBlueBufferSize(8);
108     return format;
109 }
110 
hasCapability(QPlatformIntegration::Capability cap) const111 bool QEglFSKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
112 {
113     switch (cap) {
114     case QPlatformIntegration::ThreadedPixmaps:
115     case QPlatformIntegration::OpenGL:
116     case QPlatformIntegration::ThreadedOpenGL:
117         return true;
118     default:
119         return false;
120     }
121 }
122 
waitForVSync(QPlatformSurface * surface) const123 void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const
124 {
125     QWindow *window = static_cast<QWindow *>(surface->surface());
126     QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(window->screen()->handle());
127 
128     screen->waitForFlip();
129 }
130 
supportsPBuffers() const131 bool QEglFSKmsIntegration::supportsPBuffers() const
132 {
133     return m_screenConfig->supportsPBuffers();
134 }
135 
nativeResourceForIntegration(const QByteArray & name)136 void *QEglFSKmsIntegration::nativeResourceForIntegration(const QByteArray &name)
137 {
138     if (name == QByteArrayLiteral("dri_fd") && m_device)
139         return (void *) (qintptr) m_device->fd();
140 
141 #if QT_CONFIG(drm_atomic)
142     if (name == QByteArrayLiteral("dri_atomic_request") && m_device)
143         return (void *) (qintptr) m_device->threadLocalAtomicRequest();
144 #endif
145     return nullptr;
146 }
147 
nativeResourceForScreen(const QByteArray & resource,QScreen * screen)148 void *QEglFSKmsIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *screen)
149 {
150     QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen->handle());
151     if (s) {
152         if (resource == QByteArrayLiteral("dri_crtcid"))
153             return (void *) (qintptr) s->output().crtc_id;
154         if (resource == QByteArrayLiteral("dri_connectorid"))
155             return (void *) (qintptr) s->output().connector_id;
156     }
157     return nullptr;
158 }
159 
device() const160 QKmsDevice *QEglFSKmsIntegration::device() const
161 {
162     return m_device;
163 }
164 
screenConfig() const165 QKmsScreenConfig *QEglFSKmsIntegration::screenConfig() const
166 {
167     return m_screenConfig;
168 }
169 
170 QT_END_NAMESPACE
171