File indexing completed on 2024-11-10 04:57:05
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2015 Martin Flöser <mgraesslin@kde.org> 0006 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "eglhelpers.h" 0012 #include "opengl/egldisplay.h" 0013 0014 #include <logging.h> 0015 0016 #include <QOpenGLContext> 0017 0018 namespace KWin 0019 { 0020 namespace QPA 0021 { 0022 0023 bool isOpenGLES() 0024 { 0025 if (qstrcmp(qgetenv("KWIN_COMPOSE"), "O2ES") == 0) { 0026 return true; 0027 } 0028 0029 return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES; 0030 } 0031 0032 EGLConfig configFromFormat(EglDisplay *display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType) 0033 { 0034 // std::max as these values are initialized to -1 by default. 0035 const EGLint redSize = std::max(surfaceFormat.redBufferSize(), 0); 0036 const EGLint greenSize = std::max(surfaceFormat.greenBufferSize(), 0); 0037 const EGLint blueSize = std::max(surfaceFormat.blueBufferSize(), 0); 0038 const EGLint alphaSize = std::max(surfaceFormat.alphaBufferSize(), 0); 0039 const EGLint depthSize = std::max(surfaceFormat.depthBufferSize(), 0); 0040 const EGLint stencilSize = std::max(surfaceFormat.stencilBufferSize(), 0); 0041 0042 const EGLint renderableType = isOpenGLES() ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_BIT; 0043 0044 // Not setting samples as QtQuick doesn't need it. 0045 const QList<EGLint> attributes{ 0046 EGL_SURFACE_TYPE, surfaceType, 0047 EGL_RED_SIZE, redSize, 0048 EGL_GREEN_SIZE, greenSize, 0049 EGL_BLUE_SIZE, blueSize, 0050 EGL_ALPHA_SIZE, alphaSize, 0051 EGL_DEPTH_SIZE, depthSize, 0052 EGL_STENCIL_SIZE, stencilSize, 0053 EGL_RENDERABLE_TYPE, renderableType, 0054 EGL_NONE}; 0055 0056 EGLint configCount; 0057 if (!eglChooseConfig(display->handle(), attributes.data(), nullptr, 0, &configCount)) { 0058 qCWarning(KWIN_QPA, "eglChooseConfig failed: %x", eglGetError()); 0059 return EGL_NO_CONFIG_KHR; 0060 } 0061 if (configCount == 0) { 0062 qCWarning(KWIN_QPA, "eglChooseConfig did not return any configs"); 0063 return EGL_NO_CONFIG_KHR; 0064 } 0065 0066 QList<EGLConfig> configs(configCount); 0067 if (!eglChooseConfig(display->handle(), attributes.data(), configs.data(), configCount, &configCount)) { 0068 qCWarning(KWIN_QPA, "eglChooseConfig failed: %x", eglGetError()); 0069 return EGL_NO_CONFIG_KHR; 0070 } 0071 if (configCount != configs.size()) { 0072 qCWarning(KWIN_QPA, "eglChooseConfig did not return requested configs"); 0073 return EGL_NO_CONFIG_KHR; 0074 } 0075 0076 for (const EGLConfig &config : std::as_const(configs)) { 0077 EGLint redConfig, greenConfig, blueConfig, alphaConfig; 0078 eglGetConfigAttrib(display->handle(), config, EGL_RED_SIZE, &redConfig); 0079 eglGetConfigAttrib(display->handle(), config, EGL_GREEN_SIZE, &greenConfig); 0080 eglGetConfigAttrib(display->handle(), config, EGL_BLUE_SIZE, &blueConfig); 0081 eglGetConfigAttrib(display->handle(), config, EGL_ALPHA_SIZE, &alphaConfig); 0082 0083 if ((redSize == 0 || redSize == redConfig) && (greenSize == 0 || greenSize == greenConfig) && (blueSize == 0 || blueSize == blueConfig) && (alphaSize == 0 || alphaSize == alphaConfig)) { 0084 return config; 0085 } 0086 } 0087 0088 // Return first config as a fallback. 0089 return configs[0]; 0090 } 0091 0092 QSurfaceFormat formatFromConfig(EglDisplay *display, EGLConfig config) 0093 { 0094 int redSize = 0; 0095 int blueSize = 0; 0096 int greenSize = 0; 0097 int alphaSize = 0; 0098 int stencilSize = 0; 0099 int depthSize = 0; 0100 int sampleCount = 0; 0101 0102 eglGetConfigAttrib(display->handle(), config, EGL_RED_SIZE, &redSize); 0103 eglGetConfigAttrib(display->handle(), config, EGL_GREEN_SIZE, &greenSize); 0104 eglGetConfigAttrib(display->handle(), config, EGL_BLUE_SIZE, &blueSize); 0105 eglGetConfigAttrib(display->handle(), config, EGL_ALPHA_SIZE, &alphaSize); 0106 eglGetConfigAttrib(display->handle(), config, EGL_STENCIL_SIZE, &stencilSize); 0107 eglGetConfigAttrib(display->handle(), config, EGL_DEPTH_SIZE, &depthSize); 0108 eglGetConfigAttrib(display->handle(), config, EGL_SAMPLES, &sampleCount); 0109 0110 QSurfaceFormat format; 0111 format.setRedBufferSize(redSize); 0112 format.setGreenBufferSize(greenSize); 0113 format.setBlueBufferSize(blueSize); 0114 format.setAlphaBufferSize(alphaSize); 0115 format.setStencilBufferSize(stencilSize); 0116 format.setDepthBufferSize(depthSize); 0117 format.setSamples(sampleCount); 0118 format.setRenderableType(isOpenGLES() ? QSurfaceFormat::OpenGLES : QSurfaceFormat::OpenGL); 0119 format.setStereo(false); 0120 0121 return format; 0122 } 0123 0124 } // namespace QPA 0125 } // namespace KWin