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 topWindow =
static_cast<QEglFSWindow *>(compositor->windows().last());
148 topWindow->setGeometry(screen->rawGeometry());
149 topWindow->resetSurface();
150 screen->setPrimarySurface(topWindow->surface());
151 compositor->setTargetWindow(topWindow->sourceWindow(), screen->rawGeometry());
155 if (m_flags.testFlag(HasNativeWindow)) {
156 if (screen->primarySurface() == m_surface)
157 screen->setPrimarySurface(EGL_NO_SURFACE);
166void QEglFSWindow::invalidateSurface()
168 if (m_surface != EGL_NO_SURFACE) {
169 qCDebug(qLcEglDevDebug) << Q_FUNC_INFO <<
" about to destroy EGLSurface: " << m_surface;
171 bool ok = eglDestroySurface(screen()->display(), m_surface);
174 qCWarning(qLcEglDevDebug,
"QEglFSWindow::invalidateSurface() eglDestroySurface failed!"
175 " Follow-up errors or memory leaks are possible."
176 " eglGetError(): %x", eglGetError());
179 if (eglGetCurrentSurface(EGL_READ) == m_surface ||
180 eglGetCurrentSurface(EGL_DRAW) == m_surface) {
181 bool ok = eglMakeCurrent(eglGetCurrentDisplay(), EGL_NO_DISPLAY, EGL_NO_DISPLAY, EGL_NO_CONTEXT);
182 qCDebug(qLcEglDevDebug) << Q_FUNC_INFO <<
" due to eglDestroySurface on *currently* bound surface"
183 <<
"we just called eglMakeCurrent(..,0,0,0)! It returned: " << ok;
186 if (screen()->primarySurface() == m_surface)
187 screen()->setPrimarySurface(EGL_NO_SURFACE);
189 m_surface = EGL_NO_SURFACE;
190 m_flags = m_flags & ~Created;
192 qt_egl_device_integration()->destroyNativeWindow(m_window);
196void QEglFSWindow::resetSurface()
198 EGLDisplay display = screen()->display();
199 QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat());
201 m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat);
202 m_format = q_glFormatFromConfig(display, m_config, platformFormat);
203 const QSize surfaceSize = screen()->rawGeometry().size();
204 m_window = qt_egl_device_integration()->createNativeWindow(
this, surfaceSize, m_format);
205 m_surface = eglCreateWindowSurface(display, m_config, m_window,
nullptr);
208void QEglFSWindow::setVisible(
bool visible)
211 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
212 QList<QOpenGLCompositorWindow *> windows = compositor->windows();
213 QWindow *wnd = window();
216 compositor->addWindow(
this);
218 compositor->removeWindow(
this);
219 windows = compositor->windows();
221 windows.last()->sourceWindow()->requestActivate();
224 QWindow *wnd = window();
226 QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
229 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
232void QEglFSWindow::setGeometry(
const QRect &r)
235 if (m_flags.testFlag(HasNativeWindow))
236 rect = screen()->availableGeometry();
238 QPlatformWindow::setGeometry(rect);
240 QWindowSystemInterface::handleGeometryChange(window(), rect);
242 const QRect lastReportedGeometry = qt_window_private(window())->geometry;
243 if (rect != lastReportedGeometry)
244 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
258void QEglFSWindow::requestActivateWindow()
261 QOpenGLCompositor::instance()->moveToTop(
this);
263 QWindow *wnd = window();
264 QWindowSystemInterface::handleFocusWindowChanged(wnd, Qt::ActiveWindowFocusReason);
265 QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
277void QEglFSWindow::lower()
280 QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
281 QList<QOpenGLCompositorWindow *> windows = compositor->windows();
282 if (windows.size() > 1) {
283 int idx = windows.indexOf(
this);
285 compositor->changeWindowIndex(
this, idx - 1);
286 QWindowSystemInterface::handleExposeEvent(windows.last()->sourceWindow(),
287 QRect(QPoint(0, 0), windows.last()->sourceWindow()->geometry().size()));