53void QEglFSWindow::create()
55 if (m_flags.testFlag(Created))
64 QEglFSScreen *screen =
this->screen();
66 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
67 if (screen->primarySurface() != EGL_NO_SURFACE) {
68 if (Q_UNLIKELY(isRaster() != (compositor->targetWindow() !=
nullptr))) {
72 qFatal(
"EGLFS: OpenGL windows cannot be mixed with others.");
76 m_format = compositor->targetWindow()->format();
81 m_flags |= HasNativeWindow;
86 if (Q_UNLIKELY(m_surface == EGL_NO_SURFACE)) {
87 EGLint error = eglGetError();
88 eglTerminate(screen->display());
89 qFatal(
"EGL Error : Could not create the egl surface: error = 0x%x\n", error);
92 screen->setPrimarySurface(m_surface);
95 compositor->setTargetWindow(window(), screen->rawGeometry());
96 compositor->setRotation(qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_ROTATION"));
100void QEglFSWindow::setBackingStore(QOpenGLCompositorBackingStore *backingStore)
103 if (!m_rasterCompositingContext) {
104 m_rasterCompositingContext =
new QOpenGLContext;
105 m_rasterCompositingContext->setShareContext(QOpenGLContext::globalShareContext());
106 m_rasterCompositingContext->setFormat(m_format);
107 m_rasterCompositingContext->setScreen(window()->screen());
108 if (Q_UNLIKELY(!m_rasterCompositingContext->create()))
109 qFatal(
"EGLFS: Failed to create compositing context");
112 if (!QOpenGLContext::globalShareContext())
113 qt_gl_set_global_share_context(m_rasterCompositingContext);
115 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
116 compositor->setTargetContext(m_rasterCompositingContext);
118 m_backingStore = backingStore;
121void QEglFSWindow::destroy()
123 if (!m_flags.testFlag(Created))
126 QEglFSScreen *screen =
this->screen();
128 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
129 compositor->removeWindow(
this);
130 if (compositor->targetWindow() == window()) {
131 QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(screen->cursor());
133 cursor->resetResources();
135 if (screen->primarySurface() == m_surface)
136 screen->setPrimarySurface(EGL_NO_SURFACE);
140 if (compositor->windows().isEmpty()) {
141 compositor->destroy();
142 if (QOpenGLContext::globalShareContext() == m_rasterCompositingContext)
143 qt_gl_set_global_share_context(
nullptr);
144 delete m_rasterCompositingContext;
146 auto windows = compositor->windows();
147 auto topWindow =
static_cast<QEglFSWindow *>(windows.last());
149 topWindow->setGeometry(screen->rawGeometry());
150 topWindow->resetSurface();
151 screen->setPrimarySurface(topWindow->surface());
152 compositor->setTargetWindow(topWindow->sourceWindow(), screen->rawGeometry());
156 if (m_flags.testFlag(HasNativeWindow)) {
157 if (screen->primarySurface() == m_surface)
158 screen->setPrimarySurface(EGL_NO_SURFACE);
167void QEglFSWindow::invalidateSurface()
169 if (m_surface != EGL_NO_SURFACE) {
170 qCDebug(qLcEglDevDebug) << Q_FUNC_INFO <<
" about to destroy EGLSurface: " << m_surface;
172 bool ok = eglDestroySurface(screen()->display(), m_surface);
175 qCWarning(qLcEglDevDebug,
"QEglFSWindow::invalidateSurface() eglDestroySurface failed!"
176 " Follow-up errors or memory leaks are possible."
177 " eglGetError(): %x", eglGetError());
180 if (eglGetCurrentSurface(EGL_READ) == m_surface ||
181 eglGetCurrentSurface(EGL_DRAW) == m_surface) {
182 bool ok = eglMakeCurrent(eglGetCurrentDisplay(), EGL_NO_DISPLAY, EGL_NO_DISPLAY, EGL_NO_CONTEXT);
183 qCDebug(qLcEglDevDebug) << Q_FUNC_INFO <<
" due to eglDestroySurface on *currently* bound surface"
184 <<
"we just called eglMakeCurrent(..,0,0,0)! It returned: " << ok;
187 if (screen()->primarySurface() == m_surface)
188 screen()->setPrimarySurface(EGL_NO_SURFACE);
190 m_surface = EGL_NO_SURFACE;
191 m_flags = m_flags & ~Created;
193 qt_egl_device_integration()->destroyNativeWindow(m_window);
197void QEglFSWindow::resetSurface()
199 EGLDisplay display = screen()->display();
200 QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat());
202 m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat);
203 m_format = q_glFormatFromConfig(display, m_config, platformFormat);
204 const QSize surfaceSize = screen()->rawGeometry().size();
205 m_window = qt_egl_device_integration()->createNativeWindow(
this, surfaceSize, m_format);
206 m_surface = eglCreateWindowSurface(display, m_config, m_window,
nullptr);
209void QEglFSWindow::setVisible(
bool visible)
212 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
213 QList<QOpenGLCompositorWindow *> windows = compositor->windows();
214 QWindow *wnd = window();
217 compositor->addWindow(
this);
219 compositor->removeWindow(
this);
220 windows = compositor->windows();
222 windows.last()->sourceWindow()->requestActivate();
225 QWindow *wnd = window();
227 QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
230 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
233void QEglFSWindow::setGeometry(
const QRect &r)
236 if (m_flags.testFlag(HasNativeWindow))
237 rect = screen()->availableGeometry();
239 QPlatformWindow::setGeometry(rect);
241 QWindowSystemInterface::handleGeometryChange(window(), rect);
243 const QRect lastReportedGeometry = qt_window_private(window())->geometry;
244 if (rect != lastReportedGeometry)
245 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
259void QEglFSWindow::requestActivateWindow()
262 QOpenGLCompositor::instance()->moveToTop(
this);
264 QWindow *wnd = window();
265 QWindowSystemInterface::handleFocusWindowChanged(wnd, Qt::ActiveWindowFocusReason);
266 QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
278void QEglFSWindow::lower()
281 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
282 QList<QOpenGLCompositorWindow *> windows = compositor->windows();
283 if (windows.size() > 1) {
284 int idx = windows.indexOf(
this);
286 compositor->changeWindowIndex(
this, idx - 1);
287 QWindowSystemInterface::handleExposeEvent(windows.last()->sourceWindow(),
288 QRect(QPoint(0, 0), windows.last()->sourceWindow()->geometry().size()));