52void QEglFSWindow::create()
54 if (m_flags.testFlag(Created))
63 QEglFSScreen *screen =
this->screen();
65 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
66 if (screen->primarySurface() != EGL_NO_SURFACE) {
67 if (Q_UNLIKELY(isRaster() != (compositor->targetWindow() !=
nullptr))) {
71 qFatal(
"EGLFS: OpenGL windows cannot be mixed with others.");
75 m_format = compositor->targetWindow()->format();
80 m_flags |= HasNativeWindow;
85 if (Q_UNLIKELY(m_surface == EGL_NO_SURFACE)) {
86 EGLint error = eglGetError();
87 eglTerminate(screen->display());
88 qFatal(
"EGL Error : Could not create the egl surface: error = 0x%x\n", error);
91 screen->setPrimarySurface(m_surface);
94 compositor->setTargetWindow(window(), screen->rawGeometry());
95 compositor->setRotation(qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_ROTATION"));
99void QEglFSWindow::setBackingStore(QOpenGLCompositorBackingStore *backingStore)
102 if (!m_rasterCompositingContext) {
103 m_rasterCompositingContext =
new QOpenGLContext;
104 m_rasterCompositingContext->setShareContext(QOpenGLContext::globalShareContext());
105 m_rasterCompositingContext->setFormat(m_format);
106 m_rasterCompositingContext->setScreen(window()->screen());
107 if (Q_UNLIKELY(!m_rasterCompositingContext->create()))
108 qFatal(
"EGLFS: Failed to create compositing context");
111 if (!QOpenGLContext::globalShareContext())
112 qt_gl_set_global_share_context(m_rasterCompositingContext);
114 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
115 compositor->setTargetContext(m_rasterCompositingContext);
117 m_backingStore = backingStore;
120void QEglFSWindow::destroy()
122 if (!m_flags.testFlag(Created))
125 QEglFSScreen *screen =
this->screen();
127 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
128 compositor->removeWindow(
this);
129 if (compositor->targetWindow() == window()) {
130 QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(screen->cursor());
132 cursor->resetResources();
134 if (screen->primarySurface() == m_surface)
135 screen->setPrimarySurface(EGL_NO_SURFACE);
139 if (compositor->windows().isEmpty()) {
140 compositor->destroy();
141 if (QOpenGLContext::globalShareContext() == m_rasterCompositingContext)
142 qt_gl_set_global_share_context(
nullptr);
143 delete m_rasterCompositingContext;
145 auto topWindow =
static_cast<QEglFSWindow *>(compositor->windows().last());
147 topWindow->setGeometry(screen->rawGeometry());
148 topWindow->resetSurface();
149 screen->setPrimarySurface(topWindow->surface());
150 compositor->setTargetWindow(topWindow->sourceWindow(), screen->rawGeometry());
154 if (m_flags.testFlag(HasNativeWindow)) {
155 if (screen->primarySurface() == m_surface)
156 screen->setPrimarySurface(EGL_NO_SURFACE);
165void QEglFSWindow::invalidateSurface()
167 if (m_surface != EGL_NO_SURFACE) {
168 qCDebug(qLcEglDevDebug) << Q_FUNC_INFO <<
" about to destroy EGLSurface: " << m_surface;
170 bool ok = eglDestroySurface(screen()->display(), m_surface);
173 qCWarning(qLcEglDevDebug,
"QEglFSWindow::invalidateSurface() eglDestroySurface failed!"
174 " Follow-up errors or memory leaks are possible."
175 " eglGetError(): %x", eglGetError());
178 if (eglGetCurrentSurface(EGL_READ) == m_surface ||
179 eglGetCurrentSurface(EGL_DRAW) == m_surface) {
180 bool ok = eglMakeCurrent(eglGetCurrentDisplay(), EGL_NO_DISPLAY, EGL_NO_DISPLAY, EGL_NO_CONTEXT);
181 qCDebug(qLcEglDevDebug) << Q_FUNC_INFO <<
" due to eglDestroySurface on *currently* bound surface"
182 <<
"we just called eglMakeCurrent(..,0,0,0)! It returned: " << ok;
185 if (screen()->primarySurface() == m_surface)
186 screen()->setPrimarySurface(EGL_NO_SURFACE);
188 m_surface = EGL_NO_SURFACE;
189 m_flags = m_flags & ~Created;
191 qt_egl_device_integration()->destroyNativeWindow(m_window);
195void QEglFSWindow::resetSurface()
197 EGLDisplay display = screen()->display();
198 QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat());
200 m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat);
201 m_format = q_glFormatFromConfig(display, m_config, platformFormat);
202 const QSize surfaceSize = screen()->rawGeometry().size();
203 m_window = qt_egl_device_integration()->createNativeWindow(
this, surfaceSize, m_format);
204 m_surface = eglCreateWindowSurface(display, m_config, m_window,
nullptr);
207void QEglFSWindow::setVisible(
bool visible)
210 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
211 QList<QOpenGLCompositorWindow *> windows = compositor->windows();
212 QWindow *wnd = window();
215 compositor->addWindow(
this);
217 compositor->removeWindow(
this);
218 windows = compositor->windows();
220 windows.last()->sourceWindow()->requestActivate();
223 QWindow *wnd = window();
225 QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
228 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
231void QEglFSWindow::setGeometry(
const QRect &r)
234 if (m_flags.testFlag(HasNativeWindow))
235 rect = screen()->availableGeometry();
237 QPlatformWindow::setGeometry(rect);
239 QWindowSystemInterface::handleGeometryChange(window(), rect);
241 const QRect lastReportedGeometry = qt_window_private(window())->geometry;
242 if (rect != lastReportedGeometry)
243 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
257void QEglFSWindow::requestActivateWindow()
260 QOpenGLCompositor::instance()->moveToTop(
this);
262 QWindow *wnd = window();
263 QWindowSystemInterface::handleFocusWindowChanged(wnd, Qt::ActiveWindowFocusReason);
264 QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
276void QEglFSWindow::lower()
279 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
280 QList<QOpenGLCompositorWindow *> windows = compositor->windows();
281 if (windows.size() > 1) {
282 int idx = windows.indexOf(
this);
284 compositor->changeWindowIndex(
this, idx - 1);
285 QWindowSystemInterface::handleExposeEvent(windows.last()->sourceWindow(),
286 QRect(QPoint(0, 0), windows.last()->sourceWindow()->geometry().size()));