Change bugreports.qt.nokia.com -> bugreports.qt-project.org
[profile/ivi/qtbase.git] / src / platformsupport / eglconvenience / qxlibeglintegration.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qxlibeglintegration_p.h"
43
44 static int countBits(unsigned long mask)
45 {
46     int count = 0;
47     while (mask != 0) {
48         if (mask & 1)
49             ++count;
50         mask >>= 1;
51     }
52     return count;
53 }
54
55 VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
56 {
57     VisualID    visualId = 0;
58     EGLint      eglValue = 0;
59
60     EGLint configRedSize = 0;
61     eglGetConfigAttrib(eglDisplay, config, EGL_RED_SIZE, &configRedSize);
62
63     EGLint configGreenSize = 0;
64     eglGetConfigAttrib(eglDisplay, config, EGL_GREEN_SIZE, &configGreenSize);
65
66     EGLint configBlueSize = 0;
67     eglGetConfigAttrib(eglDisplay, config, EGL_BLUE_SIZE, &configBlueSize);
68
69     EGLint configAlphaSize = 0;
70     eglGetConfigAttrib(eglDisplay, config, EGL_ALPHA_SIZE, &configAlphaSize);
71
72     eglGetConfigAttrib(eglDisplay, config, EGL_CONFIG_ID, &eglValue);
73     int configId = eglValue;
74
75     // See if EGL provided a valid VisualID:
76     eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue);
77     visualId = (VisualID)eglValue;
78     if (visualId) {
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;
83
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);
92                 return visualId;
93             }
94
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
99
100             bool visualMatchesConfig = false;
101             if ( visualRedSize == configRedSize &&
102                  visualGreenSize == configGreenSize &&
103                  visualBlueSize == configBlueSize )
104             {
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;
109                 else
110                     visualMatchesConfig = true;
111             }
112
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);
118                 } else {
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);
122                 }
123                 visualId = 0;
124             }
125         } else {
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);
128             visualId = 0;
129         }
130         XFree(chosenVisualInfo);
131     }
132 #ifdef QT_DEBUG_X11_VISUAL_SELECTION
133     else
134         qDebug("EGL did not suggest a VisualID (EGL_NATIVE_VISUAL_ID was zero) for EGLConfig %d", configId);
135 #endif
136
137     if (visualId) {
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);
141         else
142             qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, configId);
143 #endif
144         return visualId;
145     }
146
147     // Finally, try to
148     // use XGetVisualInfo and only use the bit depths to match on:
149     if (!visualId) {
150         XVisualInfo visualInfoTemplate;
151         memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
152         XVisualInfo *matchingVisuals;
153         int matchingCount = 0;
154
155         visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize;
156         matchingVisuals = XGetVisualInfo(display,
157                                          VisualDepthMask,
158                                          &visualInfoTemplate,
159                                          &matchingCount);
160         if (!matchingVisuals) {
161             // Try again without taking the alpha channel into account:
162             visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize;
163             matchingVisuals = XGetVisualInfo(display,
164                                              VisualDepthMask,
165                                              &visualInfoTemplate,
166                                              &matchingCount);
167         }
168
169         if (matchingVisuals) {
170             visualId = matchingVisuals[0].visualid;
171             XFree(matchingVisuals);
172         }
173     }
174
175     if (visualId) {
176 #ifdef QT_DEBUG_X11_VISUAL_SELECTION
177         qDebug("Using Visual ID %d provided by XGetVisualInfo for EGL config %d", (int)visualId, configId);
178 #endif
179         return visualId;
180     }
181
182     qWarning("Unable to find an X11 visual which matches EGL config %d", configId);
183     return (VisualID)0;
184 }