Changeset View
Changeset View
Standalone View
Standalone View
plugins/qpa/sharingplatformcontext.cpp
Show All 13 Lines | |||||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | 15 | GNU General Public License for more details. | ||
16 | 16 | | |||
17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | #include "sharingplatformcontext.h" | 20 | #include "sharingplatformcontext.h" | ||
21 | #include "integration.h" | 21 | #include "integration.h" | ||
22 | #include "offscreensurface.h" | ||||
22 | #include "window.h" | 23 | #include "window.h" | ||
23 | #include "../../platform.h" | 24 | #include "../../platform.h" | ||
24 | #include "../../wayland_server.h" | 25 | #include "../../wayland_server.h" | ||
25 | #include "../../shell_client.h" | 26 | #include "../../shell_client.h" | ||
26 | #include <logging.h> | 27 | #include <logging.h> | ||
27 | 28 | | |||
28 | #include <QOpenGLFramebufferObject> | 29 | #include <QOpenGLFramebufferObject> | ||
29 | #include <private/qopenglcontext_p.h> | 30 | #include <private/qopenglcontext_p.h> | ||
Show All 13 Lines | 43 | SharingPlatformContext::SharingPlatformContext(QOpenGLContext *context, const EGLSurface &surface, EGLConfig config) | |||
43 | : AbstractPlatformContext(context, kwinApp()->platform()->sceneEglDisplay(), config) | 44 | : AbstractPlatformContext(context, kwinApp()->platform()->sceneEglDisplay(), config) | ||
44 | , m_surface(surface) | 45 | , m_surface(surface) | ||
45 | { | 46 | { | ||
46 | create(); | 47 | create(); | ||
47 | } | 48 | } | ||
48 | 49 | | |||
49 | bool SharingPlatformContext::makeCurrent(QPlatformSurface *surface) | 50 | bool SharingPlatformContext::makeCurrent(QPlatformSurface *surface) | ||
50 | { | 51 | { | ||
51 | Window *window = static_cast<Window*>(surface); | 52 | EGLSurface eglSurface; | ||
53 | if (surface->surface()->surfaceClass() == QSurface::Window) { | ||||
54 | eglSurface = m_surface; | ||||
55 | } else { | ||||
56 | eglSurface = static_cast<OffscreenSurface *>(surface)->nativeHandle(); | ||||
57 | } | ||||
52 | 58 | | |||
53 | // QOpenGLContext::makeCurrent in Qt5.12 calls platfrom->setContext before setCurrentContext | 59 | const bool ok = eglMakeCurrent(eglDisplay(), eglSurface, eglSurface, eglContext()); | ||
54 | // but binding the content FBO looks up the format from the current context, so we need // to make sure sure Qt knows what the correct one is already | 60 | if (!ok) { | ||
61 | qCWarning(KWIN_QPA, "eglMakeCurrent failed: %x", eglGetError()); | ||||
62 | return false; | ||||
63 | } | ||||
64 | | ||||
65 | if (surface->surface()->surfaceClass() == QSurface::Window) { | ||||
66 | // QOpenGLContextPrivate::setCurrentContext will be called after this | ||||
67 | // method returns, but that's too late, as we need a current context in | ||||
68 | // order to bind the content framebuffer object. | ||||
55 | QOpenGLContextPrivate::setCurrentContext(context()); | 69 | QOpenGLContextPrivate::setCurrentContext(context()); | ||
56 | if (eglMakeCurrent(eglDisplay(), m_surface, m_surface, eglContext())) { | 70 | | ||
71 | Window *window = static_cast<Window *>(surface); | ||||
57 | window->bindContentFBO(); | 72 | window->bindContentFBO(); | ||
58 | return true; | | |||
59 | } | | |||
60 | qCWarning(KWIN_QPA) << "Failed to make context current"; | | |||
61 | EGLint error = eglGetError(); | | |||
62 | if (error != EGL_SUCCESS) { | | |||
63 | qCWarning(KWIN_QPA) << "EGL error code: " << error; | | |||
64 | } | 73 | } | ||
65 | 74 | | |||
66 | return false; | 75 | return true; | ||
67 | } | 76 | } | ||
68 | 77 | | |||
69 | bool SharingPlatformContext::isSharing() const | 78 | bool SharingPlatformContext::isSharing() const | ||
70 | { | 79 | { | ||
71 | return false; | 80 | return false; | ||
72 | } | 81 | } | ||
73 | 82 | | |||
74 | void SharingPlatformContext::swapBuffers(QPlatformSurface *surface) | 83 | void SharingPlatformContext::swapBuffers(QPlatformSurface *surface) | ||
75 | { | 84 | { | ||
85 | if (surface->surface()->surfaceClass() == QSurface::Window) { | ||||
76 | Window *window = static_cast<Window*>(surface); | 86 | Window *window = static_cast<Window *>(surface); | ||
77 | auto c = window->shellClient(); | 87 | auto c = window->shellClient(); | ||
78 | if (!c) { | 88 | if (!c) { | ||
79 | qCDebug(KWIN_QPA) << "SwapBuffers called but there is no ShellClient"; | 89 | qCDebug(KWIN_QPA) << "SwapBuffers called but there is no ShellClient"; | ||
80 | return; | 90 | return; | ||
81 | } | 91 | } | ||
82 | context()->makeCurrent(surface->surface()); | 92 | context()->makeCurrent(surface->surface()); | ||
83 | glFlush(); | 93 | glFlush(); | ||
84 | c->setInternalFramebufferObject(window->swapFBO()); | 94 | c->setInternalFramebufferObject(window->swapFBO()); | ||
85 | window->bindContentFBO(); | 95 | window->bindContentFBO(); | ||
romangg: You could check the opposite and return early. But not crucial. | |||||
86 | } | 96 | } | ||
97 | } | ||||
87 | 98 | | |||
romangg: pbuffers only have a back buffer and eglSwapBuffers is a no-op. | |||||
Yeah, perhaps we don't need it. QOffscreenSurface is used only to create rendering resources. zzag: Yeah, perhaps we don't need it. QOffscreenSurface is used only to create rendering resources. | |||||
88 | GLuint SharingPlatformContext::defaultFramebufferObject(QPlatformSurface *surface) const | 99 | GLuint SharingPlatformContext::defaultFramebufferObject(QPlatformSurface *surface) const | ||
89 | { | 100 | { | ||
90 | if (Window *window = dynamic_cast<Window*>(surface)) { | 101 | if (Window *window = dynamic_cast<Window*>(surface)) { | ||
romangg: qobject_cast? | |||||
zzag: QPlatformWindow is not a QObject. | |||||
romangg: Ok, then better not. Push when you're ready. | |||||
FWIW we can do if (surface->surface()->surfaceClass() == QSurface::Window) { Window *window = static_cast<Window *>(surface); } if dynamic_cast should go away. zzag: FWIW we can do
```lang=cpp
if (surface->surface()->surfaceClass() == QSurface::Window) {… | |||||
Also a good solution. Question is how often is this called if it's worth the potential performance gain. Decide before pushing what you like more and then push with or without it. romangg: Also a good solution. Question is how often is this called if it's worth the potential… | |||||
91 | const auto &fbo = window->contentFBO(); | 102 | const auto &fbo = window->contentFBO(); | ||
92 | if (!fbo.isNull()) { | 103 | if (!fbo.isNull()) { | ||
93 | return fbo->handle(); | 104 | return fbo->handle(); | ||
94 | } | 105 | } | ||
95 | } | 106 | } | ||
96 | qCDebug(KWIN_QPA) << "No default framebuffer object for internal window"; | 107 | | ||
Maybe put this debug line just inside window case in case fbo.isNull(), i.e. not remove but one line above. But not crucial. romangg: Maybe put this debug line just inside window case in case fbo.isNull(), i.e. not remove but one… | |||||
zzag: Ack, I'll move it up into the if statement. | |||||
97 | return 0; | 108 | return 0; | ||
98 | } | 109 | } | ||
99 | 110 | | |||
100 | void SharingPlatformContext::create() | 111 | void SharingPlatformContext::create() | ||
101 | { | 112 | { | ||
102 | if (config() == 0) { | 113 | if (config() == 0) { | ||
103 | qCWarning(KWIN_QPA) << "Did not get an EGL config"; | 114 | qCWarning(KWIN_QPA) << "Did not get an EGL config"; | ||
104 | return; | 115 | return; | ||
Show All 10 Lines |
You could check the opposite and return early. But not crucial.