1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qminimaleglscreen.h"
5#include "qminimaleglwindow.h"
6
7#include <QtGui/private/qeglconvenience_p.h>
8#ifndef QT_NO_OPENGL
9# include <QtGui/private/qeglplatformcontext_p.h>
10#endif
11
12#ifdef Q_OPENKODE
13#include <KD/kd.h>
14#include <KD/NV_initialize.h>
15#endif //Q_OPENKODE
16
17QT_BEGIN_NAMESPACE
18
19// #define QEGL_EXTRA_DEBUG
20
21#ifndef QT_NO_OPENGL
22
23class QMinimalEglContext : public QEGLPlatformContext
24{
25public:
26 QMinimalEglContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
27 : QEGLPlatformContext(format, share, display)
28 {
29 }
30
31 EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override
32 {
33 QMinimalEglWindow *window = static_cast<QMinimalEglWindow *>(surface);
34 QMinimalEglScreen *screen = static_cast<QMinimalEglScreen *>(window->screen());
35 return screen->surface();
36 }
37};
38
39#endif
40
41QMinimalEglScreen::QMinimalEglScreen(EGLNativeDisplayType display)
42 : m_depth(32)
43 , m_format(QImage::Format_Invalid)
44 , m_platformContext(nullptr)
45 , m_surface(nullptr)
46{
47#ifdef QEGL_EXTRA_DEBUG
48 qWarning("QEglScreen %p\n", this);
49#endif
50
51 EGLint major, minor;
52
53 if (Q_UNLIKELY(!eglBindAPI(EGL_OPENGL_ES_API))) {
54 qWarning(msg: "Could not bind GL_ES API\n");
55 qFatal(msg: "EGL error");
56 }
57
58 m_dpy = eglGetDisplay(display_id: display);
59 if (Q_UNLIKELY(m_dpy == EGL_NO_DISPLAY)) {
60 qWarning(msg: "Could not open egl display\n");
61 qFatal(msg: "EGL error");
62 }
63 qWarning(msg: "Opened display %p\n", m_dpy);
64
65 if (Q_UNLIKELY(!eglInitialize(m_dpy, &major, &minor))) {
66 qWarning(msg: "Could not initialize egl display\n");
67 qFatal(msg: "EGL error");
68 }
69
70 qWarning(msg: "Initialized display %d %d\n", major, minor);
71}
72
73QMinimalEglScreen::~QMinimalEglScreen()
74{
75 if (m_surface)
76 eglDestroySurface(dpy: m_dpy, surface: m_surface);
77
78 eglTerminate(dpy: m_dpy);
79}
80
81void QMinimalEglScreen::createAndSetPlatformContext() const {
82 const_cast<QMinimalEglScreen *>(this)->createAndSetPlatformContext();
83}
84
85void QMinimalEglScreen::createAndSetPlatformContext()
86{
87 QSurfaceFormat platformFormat;
88
89 QByteArray depthString = qgetenv(varName: "QT_QPA_EGLFS_DEPTH");
90 if (depthString.toInt() == 16) {
91 platformFormat.setDepthBufferSize(16);
92 platformFormat.setRedBufferSize(5);
93 platformFormat.setGreenBufferSize(6);
94 platformFormat.setBlueBufferSize(5);
95 m_depth = 16;
96 m_format = QImage::Format_RGB16;
97 } else {
98 platformFormat.setDepthBufferSize(24);
99 platformFormat.setStencilBufferSize(8);
100 platformFormat.setRedBufferSize(8);
101 platformFormat.setGreenBufferSize(8);
102 platformFormat.setBlueBufferSize(8);
103 m_depth = 32;
104 m_format = QImage::Format_RGB32;
105 }
106
107 if (!qEnvironmentVariableIsEmpty(varName: "QT_QPA_EGLFS_MULTISAMPLE"))
108 platformFormat.setSamples(4);
109
110 EGLConfig config = q_configFromGLFormat(display: m_dpy, format: platformFormat);
111
112 EGLNativeWindowType eglWindow = 0;
113#ifdef Q_OPENKODE
114 if (Q_UNLIKELY(kdInitializeNV() == KD_ENOTINITIALIZED))
115 qFatal("Did not manage to initialize openkode");
116
117 KDWindow *window = kdCreateWindow(m_dpy,config,0);
118
119 kdRealizeWindow(window,&eglWindow);
120#endif
121
122#ifdef QEGL_EXTRA_DEBUG
123 q_printEglConfig(m_dpy, config);
124#endif
125
126 m_surface = eglCreateWindowSurface(dpy: m_dpy, config, win: eglWindow, attrib_list: nullptr);
127 if (Q_UNLIKELY(m_surface == EGL_NO_SURFACE)) {
128 qWarning(msg: "Could not create the egl surface: error = 0x%x\n", eglGetError());
129 eglTerminate(dpy: m_dpy);
130 qFatal(msg: "EGL error");
131 }
132 // qWarning("Created surface %dx%d\n", w, h);
133
134#ifndef QT_NO_OPENGL
135 QEGLPlatformContext *platformContext = new QMinimalEglContext(platformFormat, nullptr, m_dpy);
136 m_platformContext = platformContext;
137#endif
138 EGLint w,h; // screen size detection
139 eglQuerySurface(dpy: m_dpy, surface: m_surface, EGL_WIDTH, value: &w);
140 eglQuerySurface(dpy: m_dpy, surface: m_surface, EGL_HEIGHT, value: &h);
141
142 m_geometry = QRect(0,0,w,h);
143
144}
145
146QRect QMinimalEglScreen::geometry() const
147{
148 if (m_geometry.isNull()) {
149 createAndSetPlatformContext();
150 }
151 return m_geometry;
152}
153
154int QMinimalEglScreen::depth() const
155{
156 return m_depth;
157}
158
159QImage::Format QMinimalEglScreen::format() const
160{
161 if (m_format == QImage::Format_Invalid)
162 createAndSetPlatformContext();
163 return m_format;
164}
165#ifndef QT_NO_OPENGL
166QPlatformOpenGLContext *QMinimalEglScreen::platformContext() const
167{
168 if (!m_platformContext) {
169 QMinimalEglScreen *that = const_cast<QMinimalEglScreen *>(this);
170 that->createAndSetPlatformContext();
171 }
172 return m_platformContext;
173}
174#endif
175QT_END_NAMESPACE
176

source code of qtbase/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp