1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the plugins of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qxlibeglintegration_p.h"
44 static int countBits(unsigned long mask)
55 VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
57 VisualID visualId = 0;
60 EGLint configRedSize = 0;
61 eglGetConfigAttrib(eglDisplay, config, EGL_RED_SIZE, &configRedSize);
63 EGLint configGreenSize = 0;
64 eglGetConfigAttrib(eglDisplay, config, EGL_GREEN_SIZE, &configGreenSize);
66 EGLint configBlueSize = 0;
67 eglGetConfigAttrib(eglDisplay, config, EGL_BLUE_SIZE, &configBlueSize);
69 EGLint configAlphaSize = 0;
70 eglGetConfigAttrib(eglDisplay, config, EGL_ALPHA_SIZE, &configAlphaSize);
72 eglGetConfigAttrib(eglDisplay, config, EGL_CONFIG_ID, &eglValue);
73 int configId = eglValue;
75 // See if EGL provided a valid VisualID:
76 eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue);
77 visualId = (VisualID)eglValue;
79 // EGL has suggested a visual id, so get the rest of the visual info for that id:
80 XVisualInfo visualInfoTemplate;
81 memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
82 visualInfoTemplate.visualid = visualId;
84 XVisualInfo *chosenVisualInfo;
85 int matchingCount = 0;
86 chosenVisualInfo = XGetVisualInfo(display, VisualIDMask, &visualInfoTemplate, &matchingCount);
87 if (chosenVisualInfo) {
88 // Skip size checks if implementation supports non-matching visual
89 // and config (http://bugreports.qt-project.org/browse/QTBUG-9444).
90 if (q_hasEglExtension(eglDisplay,"EGL_NV_post_convert_rounding")) {
91 XFree(chosenVisualInfo);
95 int visualRedSize = countBits(chosenVisualInfo->red_mask);
96 int visualGreenSize = countBits(chosenVisualInfo->green_mask);
97 int visualBlueSize = countBits(chosenVisualInfo->blue_mask);
98 int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
100 bool visualMatchesConfig = false;
101 if ( visualRedSize == configRedSize &&
102 visualGreenSize == configGreenSize &&
103 visualBlueSize == configBlueSize )
105 // We need XRender to check the alpha channel size of the visual. If we don't have
106 // the alpha size, we don't check it against the EGL config's alpha size.
107 if (visualAlphaSize >= 0)
108 visualMatchesConfig = visualAlphaSize == configAlphaSize;
110 visualMatchesConfig = true;
113 if (!visualMatchesConfig) {
114 if (visualAlphaSize >= 0) {
115 qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable",
116 (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize,
117 configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize);
119 qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable",
120 (int)visualId, visualRedSize, visualGreenSize, visualBlueSize,
121 configId, configRedSize, configGreenSize, configBlueSize);
126 qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID",
127 (int)visualId, configId);
130 XFree(chosenVisualInfo);
132 #ifdef QT_DEBUG_X11_VISUAL_SELECTION
134 qDebug("EGL did not suggest a VisualID (EGL_NATIVE_VISUAL_ID was zero) for EGLConfig %d", configId);
138 #ifdef QT_DEBUG_X11_VISUAL_SELECTION
139 if (configAlphaSize > 0)
140 qDebug("Using ARGB Visual ID %d provided by EGL for config %d", (int)visualId, configId);
142 qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, configId);
148 // use XGetVisualInfo and only use the bit depths to match on:
150 XVisualInfo visualInfoTemplate;
151 memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
152 XVisualInfo *matchingVisuals;
153 int matchingCount = 0;
155 visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize;
156 matchingVisuals = XGetVisualInfo(display,
160 if (!matchingVisuals) {
161 // Try again without taking the alpha channel into account:
162 visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize;
163 matchingVisuals = XGetVisualInfo(display,
169 if (matchingVisuals) {
170 visualId = matchingVisuals[0].visualid;
171 XFree(matchingVisuals);
176 #ifdef QT_DEBUG_X11_VISUAL_SELECTION
177 qDebug("Using Visual ID %d provided by XGetVisualInfo for EGL config %d", (int)visualId, configId);
182 qWarning("Unable to find an X11 visual which matches EGL config %d", configId);