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 "qeglfsglobal_p.h" |
5 | #include <QtGui/QSurface> |
6 | #include <QtGui/private/qeglconvenience_p.h> |
7 | #include <QtGui/private/qeglpbuffer_p.h> |
8 | |
9 | #include "qeglfscontext_p.h" |
10 | #include "qeglfswindow_p.h" |
11 | #include "qeglfshooks_p.h" |
12 | #include "qeglfscursor_p.h" |
13 | |
14 | QT_BEGIN_NAMESPACE |
15 | |
16 | QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, |
17 | EGLConfig *config) |
18 | : QEGLPlatformContext(format, share, display, config, |
19 | qt_egl_device_integration()->supportsSurfacelessContexts() ? Flags() : QEGLPlatformContext::NoSurfaceless) |
20 | { |
21 | } |
22 | |
23 | EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) |
24 | { |
25 | if (surface->surface()->surfaceClass() == QSurface::Window) { |
26 | |
27 | QEglFSWindow *w = static_cast<QEglFSWindow *>(surface); |
28 | EGLSurface s = w->surface(); |
29 | if (s == EGL_NO_SURFACE) { |
30 | w->resetSurface(); |
31 | s = w->surface(); |
32 | } |
33 | return s; |
34 | |
35 | } else { |
36 | return static_cast<QEGLPbuffer *>(surface)->pbuffer(); |
37 | } |
38 | } |
39 | |
40 | EGLSurface QEglFSContext::createTemporaryOffscreenSurface() |
41 | { |
42 | if (qt_egl_device_integration()->supportsPBuffers()) |
43 | return QEGLPlatformContext::createTemporaryOffscreenSurface(); |
44 | |
45 | if (!m_tempWindow) { |
46 | m_tempWindow = qt_egl_device_integration()->createNativeOffscreenWindow(format: format()); |
47 | if (!m_tempWindow) { |
48 | qWarning(msg: "QEglFSContext: Failed to create temporary native window" ); |
49 | return EGL_NO_SURFACE; |
50 | } |
51 | } |
52 | EGLConfig config = q_configFromGLFormat(display: eglDisplay(), format: format()); |
53 | return eglCreateWindowSurface(dpy: eglDisplay(), config, win: m_tempWindow, attrib_list: nullptr); |
54 | } |
55 | |
56 | void QEglFSContext::destroyTemporaryOffscreenSurface(EGLSurface surface) |
57 | { |
58 | if (qt_egl_device_integration()->supportsPBuffers()) { |
59 | QEGLPlatformContext::destroyTemporaryOffscreenSurface(surface); |
60 | } else { |
61 | eglDestroySurface(dpy: eglDisplay(), surface); |
62 | qt_egl_device_integration()->destroyNativeWindow(window: m_tempWindow); |
63 | m_tempWindow = 0; |
64 | } |
65 | } |
66 | |
67 | void QEglFSContext::runGLChecks() |
68 | { |
69 | // Note that even though there is an EGL context current here, |
70 | // QOpenGLContext and QOpenGLFunctions are not yet usable at this stage. |
71 | const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); |
72 | // Be nice and warn about a common source of confusion. |
73 | if (renderer && strstr(haystack: renderer, needle: "llvmpipe" )) |
74 | qWarning(msg: "Running on a software rasterizer (LLVMpipe), expect limited performance." ); |
75 | } |
76 | |
77 | void QEglFSContext::swapBuffers(QPlatformSurface *surface) |
78 | { |
79 | // draw the cursor |
80 | if (surface->surface()->surfaceClass() == QSurface::Window) { |
81 | QPlatformWindow *window = static_cast<QPlatformWindow *>(surface); |
82 | if (QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(object: window->screen()->cursor())) |
83 | cursor->paintOnScreen(); |
84 | } |
85 | |
86 | qt_egl_device_integration()->waitForVSync(surface); |
87 | QEGLPlatformContext::swapBuffers(surface); |
88 | qt_egl_device_integration()->presentBuffer(surface); |
89 | } |
90 | |
91 | QT_END_NAMESPACE |
92 | |