Qt 4.8
qxlibeglintegration.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qxlibeglintegration.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 }
static int countBits(unsigned long mask)
Q_CORE_EXPORT void qDebug(const char *,...)
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
static VisualID getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
Q_CORE_EXPORT void qWarning(const char *,...)
struct _XDisplay Display
Definition: qwindowdefs.h:115
bool q_hasEglExtension(EGLDisplay display, const char *extensionName)