diff --git a/plugins/qpa/CMakeLists.txt b/plugins/qpa/CMakeLists.txt --- a/plugins/qpa/CMakeLists.txt +++ b/plugins/qpa/CMakeLists.txt @@ -4,6 +4,7 @@ set(QPA_SOURCES abstractplatformcontext.cpp backingstore.cpp + eglhelpers.cpp integration.cpp main.cpp nativeinterface.cpp diff --git a/plugins/qpa/abstractplatformcontext.cpp b/plugins/qpa/abstractplatformcontext.cpp --- a/plugins/qpa/abstractplatformcontext.cpp +++ b/plugins/qpa/abstractplatformcontext.cpp @@ -18,88 +18,25 @@ along with this program. If not, see . *********************************************************************/ #include "abstractplatformcontext.h" -#include "integration.h" #include "egl_context_attribute_builder.h" +#include "eglhelpers.h" + #include +#include + #include namespace KWin { namespace QPA { -static bool isOpenGLES() -{ - if (qstrcmp(qgetenv("KWIN_COMPOSE"), "O2ES") == 0) { - return true; - } - return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES; -} - -static EGLConfig configFromGLFormat(EGLDisplay dpy, const QSurfaceFormat &format) -{ -#define SIZE( __buffer__ ) format.__buffer__##BufferSize() > 0 ? format.__buffer__##BufferSize() : 0 - // not setting samples as QtQuick doesn't need it - const EGLint config_attribs[] = { - EGL_SURFACE_TYPE, 0, - EGL_RED_SIZE, SIZE(red), - EGL_GREEN_SIZE, SIZE(green), - EGL_BLUE_SIZE, SIZE(blue), - EGL_ALPHA_SIZE, SIZE(alpha), - EGL_DEPTH_SIZE, SIZE(depth), - EGL_STENCIL_SIZE, SIZE(stencil), - EGL_RENDERABLE_TYPE, isOpenGLES() ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_BIT, - EGL_NONE, - }; - qCDebug(KWIN_QPA) << "Trying to find a format with: rgba/depth/stencil" << (SIZE(red)) << (SIZE(green)) <<( SIZE(blue)) << (SIZE(alpha)) << (SIZE(depth)) << (SIZE(stencil)); -#undef SIZE - - EGLint count; - EGLConfig configs[1024]; - if (eglChooseConfig(dpy, config_attribs, configs, 1, &count) == EGL_FALSE) { - qCWarning(KWIN_QPA) << "eglChooseConfig failed"; - return 0; - } - if (count != 1) { - qCWarning(KWIN_QPA) << "eglChooseConfig did not return any configs"; - return 0; - } - return configs[0]; -} - -static QSurfaceFormat formatFromConfig(EGLDisplay dpy, EGLConfig config) -{ - QSurfaceFormat format; - EGLint value = 0; -#define HELPER(__egl__, __qt__) \ - eglGetConfigAttrib(dpy, config, EGL_##__egl__, &value); \ - format.set##__qt__(value); \ - value = 0; - -#define BUFFER_HELPER(__eglColor__, __color__) \ - HELPER(__eglColor__##_SIZE, __color__##BufferSize) - - BUFFER_HELPER(RED, Red) - BUFFER_HELPER(GREEN, Green) - BUFFER_HELPER(BLUE, Blue) - BUFFER_HELPER(ALPHA, Alpha) - BUFFER_HELPER(STENCIL, Stencil) - BUFFER_HELPER(DEPTH, Depth) -#undef BUFFER_HELPER - HELPER(SAMPLES, Samples) -#undef HELPER - format.setRenderableType(isOpenGLES() ? QSurfaceFormat::OpenGLES : QSurfaceFormat::OpenGL); - format.setStereo(false); - - return format; -} - AbstractPlatformContext::AbstractPlatformContext(QOpenGLContext *context, EGLDisplay display, EGLConfig config) : QPlatformOpenGLContext() , m_eglDisplay(display) - , m_config(config ? config :configFromGLFormat(m_eglDisplay, context->format())) + , m_config(config ? config : configFromFormat(m_eglDisplay, context->format())) , m_format(formatFromConfig(m_eglDisplay, m_config)) { } diff --git a/plugins/qpa/eglhelpers.h b/plugins/qpa/eglhelpers.h new file mode 100644 --- /dev/null +++ b/plugins/qpa/eglhelpers.h @@ -0,0 +1,40 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2019 Vlad Zagorodniy + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#pragma once + +#define MESA_EGL_NO_X11_HEADERS +#include +#include "fixqopengl.h" + +#include + +namespace KWin +{ +namespace QPA +{ + +bool isOpenGLES(); + +EGLConfig configFromFormat(EGLDisplay display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType = 0); +QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config); + +} // namespace QPA +} // namespace KWin diff --git a/plugins/qpa/eglhelpers.cpp b/plugins/qpa/eglhelpers.cpp new file mode 100644 --- /dev/null +++ b/plugins/qpa/eglhelpers.cpp @@ -0,0 +1,116 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2015 Martin Flöser +Copyright (C) 2019 Vlad Zagorodniy + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +#include "eglhelpers.h" + +#include + +#include + +namespace KWin +{ +namespace QPA +{ + +bool isOpenGLES() +{ + if (qstrcmp(qgetenv("KWIN_COMPOSE"), "O2ES") == 0) { + return true; + } + + return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES; +} + +EGLConfig configFromFormat(EGLDisplay display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType) +{ + // qMax as these values are initialized to -1 by default. + const EGLint redSize = qMax(surfaceFormat.redBufferSize(), 0); + const EGLint greenSize = qMax(surfaceFormat.greenBufferSize(), 0); + const EGLint blueSize = qMax(surfaceFormat.blueBufferSize(), 0); + const EGLint alphaSize = qMax(surfaceFormat.alphaBufferSize(), 0); + const EGLint depthSize = qMax(surfaceFormat.depthBufferSize(), 0); + const EGLint stencilSize = qMax(surfaceFormat.stencilBufferSize(), 0); + + const EGLint renderableType = isOpenGLES() ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_BIT; + + // Not setting samples as QtQuick doesn't need it. + const QVector attributes { + EGL_SURFACE_TYPE, surfaceType, + EGL_RED_SIZE, redSize, + EGL_GREEN_SIZE, greenSize, + EGL_BLUE_SIZE, blueSize, + EGL_ALPHA_SIZE, alphaSize, + EGL_DEPTH_SIZE, depthSize, + EGL_STENCIL_SIZE, stencilSize, + EGL_RENDERABLE_TYPE, renderableType, + EGL_NONE + }; + + EGLint configCount; + EGLConfig configs[1024]; + if (!eglChooseConfig(display, attributes.data(), configs, 1, &configCount)) { + // FIXME: Don't bail out yet, we should try to find the most suitable config. + qCWarning(KWIN_QPA, "eglChooseConfig failed: %x", eglGetError()); + return EGL_NO_CONFIG_KHR; + } + + if (configCount != 1) { + qCWarning(KWIN_QPA) << "eglChooseConfig did not return any configs"; + return EGL_NO_CONFIG_KHR; + } + + return configs[0]; +} + +QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config) +{ + int redSize = 0; + int blueSize = 0; + int greenSize = 0; + int alphaSize = 0; + int stencilSize = 0; + int depthSize = 0; + int sampleCount = 0; + + eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); + eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); + eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); + eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize); + eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize); + eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize); + eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount); + + QSurfaceFormat format; + format.setRedBufferSize(redSize); + format.setGreenBufferSize(greenSize); + format.setBlueBufferSize(blueSize); + format.setAlphaBufferSize(alphaSize); + format.setStencilBufferSize(stencilSize); + format.setDepthBufferSize(depthSize); + format.setSamples(sampleCount); + format.setRenderableType(isOpenGLES() ? QSurfaceFormat::OpenGLES : QSurfaceFormat::OpenGL); + format.setStereo(false); + + return format; +} + +} // namespace QPA +} // namespace KWin