Qt 4.8
qeglproperties.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 QtGui module 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 <QtCore/qdebug.h>
43 #include <QtCore/qstringlist.h>
44 
45 #include "qeglproperties_p.h"
46 #include "qeglcontext_p.h"
47 
49 
50 // Initialize a property block.
52 {
53  props.append(EGL_NONE);
54 }
55 
57 {
58  props.append(EGL_NONE);
59  for (int name = 0x3020; name <= 0x304F; ++name) {
60  EGLint value;
61  if (name != EGL_NONE && eglGetConfigAttrib(QEgl::display(), cfg, name, &value))
62  setValue(name, value);
63  }
64  eglGetError(); // Clear the error state.
65 }
66 
67 // Fetch the current value associated with a property.
69 {
70  for (int index = 0; index < (props.size() - 1); index += 2) {
71  if (props[index] == name)
72  return props[index + 1];
73  }
74 
75  // If the attribute has not been explicitly set, return the EGL default
76  // The following defaults were taken from the EGL 1.4 spec:
77  switch(name) {
78  case EGL_BUFFER_SIZE: return 0;
79  case EGL_RED_SIZE: return 0;
80  case EGL_GREEN_SIZE: return 0;
81  case EGL_BLUE_SIZE: return 0;
82  case EGL_ALPHA_SIZE: return 0;
83 #ifdef EGL_LUMINANCE_SIZE
84  case EGL_LUMINANCE_SIZE: return 0;
85 #endif
86 #ifdef EGL_ALPHA_MASK_SIZE
87  case EGL_ALPHA_MASK_SIZE: return 0;
88 #endif
89 #ifdef EGL_BIND_TO_TEXTURE_RGB
90  case EGL_BIND_TO_TEXTURE_RGB: return EGL_DONT_CARE;
91 #endif
92 #ifdef EGL_BIND_TO_TEXTURE_RGBA
93  case EGL_BIND_TO_TEXTURE_RGBA: return EGL_DONT_CARE;
94 #endif
95 #ifdef EGL_COLOR_BUFFER_TYPE
96  case EGL_COLOR_BUFFER_TYPE: return EGL_RGB_BUFFER;
97 #endif
98  case EGL_CONFIG_CAVEAT: return EGL_DONT_CARE;
99  case EGL_CONFIG_ID: return EGL_DONT_CARE;
100  case EGL_DEPTH_SIZE: return 0;
101  case EGL_LEVEL: return 0;
102  case EGL_NATIVE_RENDERABLE: return EGL_DONT_CARE;
103  case EGL_NATIVE_VISUAL_TYPE: return EGL_DONT_CARE;
104  case EGL_MAX_SWAP_INTERVAL: return EGL_DONT_CARE;
105  case EGL_MIN_SWAP_INTERVAL: return EGL_DONT_CARE;
106 #ifdef EGL_RENDERABLE_TYPE
107  case EGL_RENDERABLE_TYPE: return EGL_OPENGL_ES_BIT;
108 #endif
109  case EGL_SAMPLE_BUFFERS: return 0;
110  case EGL_SAMPLES: return 0;
111  case EGL_STENCIL_SIZE: return 0;
112  case EGL_SURFACE_TYPE: return EGL_WINDOW_BIT;
113  case EGL_TRANSPARENT_TYPE: return EGL_NONE;
114  case EGL_TRANSPARENT_RED_VALUE: return EGL_DONT_CARE;
115  case EGL_TRANSPARENT_GREEN_VALUE: return EGL_DONT_CARE;
116  case EGL_TRANSPARENT_BLUE_VALUE: return EGL_DONT_CARE;
117 
118 #ifdef EGL_VERSION_1_3
119  case EGL_CONFORMANT: return 0;
120  case EGL_MATCH_NATIVE_PIXMAP: return EGL_NONE;
121 #endif
122 
123  case EGL_MAX_PBUFFER_HEIGHT:
124  case EGL_MAX_PBUFFER_WIDTH:
125  case EGL_MAX_PBUFFER_PIXELS:
126  case EGL_NATIVE_VISUAL_ID:
127  case EGL_NONE:
128  // Attribute does not affect config selection.
129  return EGL_DONT_CARE;
130  default:
131  // Attribute is unknown in EGL <= 1.4.
132  return EGL_DONT_CARE;
133  }
134 }
135 
136 // Set the value associated with a property, replacing an existing
137 // value if there is one.
139 {
140  for (int index = 0; index < (props.size() - 1); index += 2) {
141  if (props[index] == name) {
142  props[index + 1] = value;
143  return;
144  }
145  }
146  props[props.size() - 1] = name;
147  props.append(value);
148  props.append(EGL_NONE);
149 }
150 
151 // Remove a property value. Returns false if the property is not present.
153 {
154  for (int index = 0; index < (props.size() - 1); index += 2) {
155  if (props[index] == name) {
156  while ((index + 2) < props.size()) {
157  props[index] = props[index + 2];
158  ++index;
159  }
160  props.resize(props.size() - 2);
161  return true;
162  }
163  }
164  return false;
165 }
166 
168 {
169  if (devType == QInternal::Pixmap || devType == QInternal::Image)
170  setValue(EGL_SURFACE_TYPE, EGL_PIXMAP_BIT);
171  else if (devType == QInternal::Pbuffer)
172  setValue(EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
173  else
174  setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
175 }
176 
177 
178 // Sets the red, green, blue, and alpha sizes based on a pixel format.
179 // Normally used to match a configuration request to the screen format.
181 {
182  int red, green, blue, alpha;
183  switch (pixelFormat) {
186  red = green = blue = 8; alpha = 0; break;
189  red = green = blue = alpha = 8; break;
191  red = 5; green = 6; blue = 5; alpha = 0; break;
193  red = 5; green = 6; blue = 5; alpha = 8; break;
195  red = green = blue = 6; alpha = 0; break;
197  red = green = blue = alpha = 6; break;
199  red = green = blue = 5; alpha = 0; break;
201  red = green = blue = 5; alpha = 8; break;
203  red = green = blue = 4; alpha = 0; break;
205  red = green = blue = alpha = 4; break;
206  default:
207  qWarning() << "QEglProperties::setPixelFormat(): Unsupported pixel format";
208  red = green = blue = alpha = 1; break;
209  }
210  setValue(EGL_RED_SIZE, red);
211  setValue(EGL_GREEN_SIZE, green);
212  setValue(EGL_BLUE_SIZE, blue);
213  setValue(EGL_ALPHA_SIZE, alpha);
214 }
215 
217 {
218 #ifdef EGL_RENDERABLE_TYPE
219 #if defined(QT_OPENGL_ES_2)
220  if (api == QEgl::OpenGL)
221  setValue(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT);
222 #elif defined(QT_OPENGL_ES)
223  if (api == QEgl::OpenGL)
224  setValue(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT);
225 #elif defined(EGL_OPENGL_BIT)
226  if (api == QEgl::OpenGL)
227  setValue(EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT);
228 #endif
229 #ifdef EGL_OPENVG_BIT
230  if (api == QEgl::OpenVG)
231  setValue(EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT);
232 #endif
233 #else
234  Q_UNUSED(api);
235 #endif
236 }
237 
238 // Reduce the complexity of a configuration request to ask for less
239 // because the previous request did not result in success. Returns
240 // true if the complexity was reduced, or false if no further
241 // reductions in complexity are possible.
243 {
244 #ifdef EGL_SWAP_BEHAVIOR
245  if (value(EGL_SWAP_BEHAVIOR) != EGL_DONT_CARE)
246  removeValue(EGL_SWAP_BEHAVIOR);
247 #endif
248 
249 #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
250  // For OpenVG, we sometimes try to create a surface using a pre-multiplied format. If we can't
251  // find a config which supports pre-multiplied formats, remove the flag on the surface type:
252  EGLint surfaceType = value(EGL_SURFACE_TYPE);
253  if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) {
254  surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT;
255  setValue(EGL_SURFACE_TYPE, surfaceType);
256  return true;
257  }
258 #endif
259  // EGL chooses configs with the highest color depth over
260  // those with smaller (but faster) lower color depths. One
261  // way around this is to set EGL_BUFFER_SIZE to 16, which
262  // trumps the others. Of course, there may not be a 16-bit
263  // config available, so it's the first restraint we remove.
264  if (value(EGL_BUFFER_SIZE) == 16) {
265  removeValue(EGL_BUFFER_SIZE);
266  return true;
267  }
268  if (removeValue(EGL_SAMPLE_BUFFERS)) {
269  removeValue(EGL_SAMPLES);
270  return true;
271  }
272  if (removeValue(EGL_ALPHA_SIZE)) {
273 #if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB)
274  if (removeValue(EGL_BIND_TO_TEXTURE_RGBA))
275  setValue(EGL_BIND_TO_TEXTURE_RGB, TRUE);
276 #endif
277  return true;
278  }
279  if (removeValue(EGL_STENCIL_SIZE))
280  return true;
281  if (removeValue(EGL_DEPTH_SIZE))
282  return true;
283 #ifdef EGL_BIND_TO_TEXTURE_RGB
284  if (removeValue(EGL_BIND_TO_TEXTURE_RGB))
285  return true;
286 #endif
287  return false;
288 }
289 
290 static void addTag(QString& str, const QString& tag)
291 {
292  int lastnl = str.lastIndexOf(QLatin1String("\n"));
293  if (lastnl == -1)
294  lastnl = 0;
295  if ((str.length() - lastnl) >= 50)
296  str += QLatin1String("\n ");
297  str += tag;
298 }
299 
300 // Convert a property list to a string suitable for debug output.
302 {
303  QString str;
304  int val;
305 
306  val = value(EGL_CONFIG_ID);
307  if (val != EGL_DONT_CARE) {
308  str += QLatin1String("id=");
309  str += QString::number(val);
310  str += QLatin1Char(' ');
311  }
312 
313 #ifdef EGL_RENDERABLE_TYPE
314  val = value(EGL_RENDERABLE_TYPE);
315  if (val != EGL_DONT_CARE) {
316  str += QLatin1String("type=");
318  if ((val & EGL_OPENGL_ES_BIT) != 0)
319  types += QLatin1String("es1");
320 #ifdef EGL_OPENGL_ES2_BIT
321  if ((val & EGL_OPENGL_ES2_BIT) != 0)
322  types += QLatin1String("es2");
323 #endif
324 #ifdef EGL_OPENGL_BIT
325  if ((val & EGL_OPENGL_BIT) != 0)
326  types += QLatin1String("gl");
327 #endif
328  if ((val & EGL_OPENVG_BIT) != 0)
329  types += QLatin1String("vg");
330  if ((val & ~7) != 0)
331  types += QString::number(val);
332  str += types.join(QLatin1String(","));
333  } else {
334  str += QLatin1String("type=any");
335  }
336 #else
337  str += QLatin1String("type=es1");
338 #endif
339 
340  int red = value(EGL_RED_SIZE);
341  int green = value(EGL_GREEN_SIZE);
342  int blue = value(EGL_BLUE_SIZE);
343  int alpha = value(EGL_ALPHA_SIZE);
344  int bufferSize = value(EGL_BUFFER_SIZE);
345  if (bufferSize == (red + green + blue + alpha))
346  bufferSize = 0;
347  str += QLatin1String(" rgba=");
348  str += QString::number(red);
349  str += QLatin1Char(',');
350  str += QString::number(green);
351  str += QLatin1Char(',');
352  str += QString::number(blue);
353  str += QLatin1Char(',');
354  str += QString::number(alpha);
355  if (bufferSize != 0) {
356  // Only report buffer size if different than r+g+b+a.
357  str += QLatin1String(" buffer-size=");
358  str += QString::number(bufferSize);
359  }
360 
361 #ifdef EGL_COLOR_BUFFER_TYPE
362  val = value(EGL_COLOR_BUFFER_TYPE);
363  if (val == EGL_LUMINANCE_BUFFER) {
364  addTag(str, QLatin1String(" color-buffer-type=luminance"));
365  } else if (val != EGL_DONT_CARE && val != EGL_RGB_BUFFER) {
366  addTag(str, QLatin1String(" color-buffer-type="));
367  str += QString::number(val, 16);
368  }
369 #endif
370 
371  val = value(EGL_DEPTH_SIZE);
372  if (val != 0) {
373  addTag(str, QLatin1String(" depth="));
374  str += QString::number(val);
375  }
376 
377  val = value(EGL_STENCIL_SIZE);
378  if (val != 0) {
379  addTag(str, QLatin1String(" stencil="));
380  str += QString::number(val);
381  }
382 
383  val = value(EGL_SURFACE_TYPE);
384  if (val != EGL_DONT_CARE) {
385  addTag(str, QLatin1String(" surface-type="));
387  if ((val & EGL_WINDOW_BIT) != 0)
388  types += QLatin1String("window");
389  if ((val & EGL_PIXMAP_BIT) != 0)
390  types += QLatin1String("pixmap");
391  if ((val & EGL_PBUFFER_BIT) != 0)
392  types += QLatin1String("pbuffer");
393 #ifdef EGL_VG_COLORSPACE_LINEAR_BIT
394  if ((val & EGL_VG_COLORSPACE_LINEAR_BIT) != 0)
395  types += QLatin1String("vg-colorspace-linear");
396 #endif
397 #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
398  if ((val & EGL_VG_ALPHA_FORMAT_PRE_BIT) != 0)
399  types += QLatin1String("vg-alpha-format-pre");
400 #endif
401  if ((val & ~(EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT
402 #ifdef EGL_VG_COLORSPACE_LINEAR_BIT
403  | EGL_VG_COLORSPACE_LINEAR_BIT
404 #endif
405 #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
406  | EGL_VG_ALPHA_FORMAT_PRE_BIT
407 #endif
408  )) != 0) {
409  types += QString::number(val);
410  }
411  str += types.join(QLatin1String(","));
412  }
413 
414  val = value(EGL_CONFIG_CAVEAT);
415  if (val != EGL_DONT_CARE) {
416  addTag(str, QLatin1String(" caveat="));
417  if (val == EGL_NONE)
418  str += QLatin1String("none");
419  else if (val == EGL_SLOW_CONFIG)
420  str += QLatin1String("slow");
421  else if (val == EGL_NON_CONFORMANT_CONFIG)
422  str += QLatin1String("non-conformant");
423  else
424  str += QString::number(val, 16);
425  }
426 
427  val = value(EGL_LEVEL);
428  if (val != 0) {
429  addTag(str, QLatin1String(" level="));
430  str += QString::number(val);
431  }
432 
433  int width, height, pixels;
434  width = value(EGL_MAX_PBUFFER_WIDTH);
435  height = value(EGL_MAX_PBUFFER_HEIGHT);
436  pixels = value(EGL_MAX_PBUFFER_PIXELS);
437  if (height != EGL_DONT_CARE || width != EGL_DONT_CARE) {
438  addTag(str, QLatin1String(" max-pbuffer-size="));
439  str += QString::number(width);
440  str += QLatin1Char('x');
441  str += QString::number(height);
442  if (pixels != (width * height)) {
443  addTag(str, QLatin1String(" max-pbuffer-pixels="));
444  str += QString::number(pixels);
445  }
446  }
447 
448  val = value(EGL_NATIVE_RENDERABLE);
449  if (val != EGL_DONT_CARE) {
450  if (val)
451  addTag(str, QLatin1String(" native-renderable=true"));
452  else
453  addTag(str, QLatin1String(" native-renderable=false"));
454  }
455 
456  val = value(EGL_NATIVE_VISUAL_ID);
457  if (val != EGL_DONT_CARE) {
458  addTag(str, QLatin1String(" visual-id="));
459  str += QString::number(val);
460  }
461 
462  val = value(EGL_NATIVE_VISUAL_TYPE);
463  if (val != EGL_DONT_CARE) {
464  addTag(str, QLatin1String(" visual-type="));
465  str += QString::number(val);
466  }
467 
468 #ifdef EGL_PRESERVED_RESOURCES
469  val = value(EGL_PRESERVED_RESOURCES);
470  if (val != EGL_DONT_CARE) {
471  if (val)
472  addTag(str, QLatin1String(" preserved-resources=true"));
473  else
474  addTag(str, QLatin1String(" preserved-resources=false"));
475  }
476 #endif
477 
478  val = value(EGL_SAMPLES);
479  if (val != 0) {
480  addTag(str, QLatin1String(" samples="));
481  str += QString::number(val);
482  }
483 
484  val = value(EGL_SAMPLE_BUFFERS);
485  if (val != 0) {
486  addTag(str, QLatin1String(" sample-buffers="));
487  str += QString::number(val);
488  }
489 
490  val = value(EGL_TRANSPARENT_TYPE);
491  if (val == EGL_TRANSPARENT_RGB) {
492  addTag(str, QLatin1String(" transparent-rgb="));
493  str += QString::number(value(EGL_TRANSPARENT_RED_VALUE));
494  str += QLatin1Char(',');
495  str += QString::number(value(EGL_TRANSPARENT_GREEN_VALUE));
496  str += QLatin1Char(',');
497  str += QString::number(value(EGL_TRANSPARENT_BLUE_VALUE));
498  }
499 
500 #if defined(EGL_BIND_TO_TEXTURE_RGB) && defined(EGL_BIND_TO_TEXTURE_RGBA)
501  val = value(EGL_BIND_TO_TEXTURE_RGB);
502  int val2 = value(EGL_BIND_TO_TEXTURE_RGBA);
503  if (val != EGL_DONT_CARE || val2 != EGL_DONT_CARE) {
504  addTag(str, QLatin1String(" bind-texture="));
505  if (val == EGL_TRUE)
506  str += QLatin1String("rgb");
507  else
508  str += QLatin1String("no-rgb");
509  if (val2 == EGL_TRUE)
510  str += QLatin1String(",rgba");
511  else
512  str += QLatin1String(",no-rgba");
513  }
514 #endif
515 
516 #ifdef EGL_MIN_SWAP_INTERVAL
517  val = value(EGL_MIN_SWAP_INTERVAL);
518  if (val != EGL_DONT_CARE) {
519  addTag(str, QLatin1String(" min-swap-interval="));
520  str += QString::number(val);
521  }
522 #endif
523 
524 #ifdef EGL_MIN_SWAP_INTERVAL
525  val = value(EGL_MAX_SWAP_INTERVAL);
526  if (val != EGL_DONT_CARE) {
527  addTag(str, QLatin1String(" max-swap-interval="));
528  str += QString::number(val);
529  }
530 #endif
531 
532 #ifdef EGL_LUMINANCE_SIZE
533  val = value(EGL_LUMINANCE_SIZE);
534  if (val != 0) {
535  addTag(str, QLatin1String(" luminance="));
536  str += QString::number(val);
537  }
538 #endif
539 
540 #ifdef EGL_ALPHA_MASK_SIZE
541  val = value(EGL_ALPHA_MASK_SIZE);
542  if (val != 0) {
543  addTag(str, QLatin1String(" alpha-mask="));
544  str += QString::number(val);
545  }
546 #endif
547 
548 #ifdef EGL_CONFORMANT
549  val = value(EGL_CONFORMANT);
550  if (val != 0) {
551  if (val)
552  addTag(str, QLatin1String(" conformant=true"));
553  else
554  addTag(str, QLatin1String(" conformant=false"));
555  }
556 #endif
557 
558  return str;
559 }
560 
562 
563 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
void resize(int size)
Format
The following image formats are available in Qt.
Definition: qimage.h:91
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
bool removeValue(int name)
QString toString() const
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
int value(int name) const
int width() const
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QString class provides a Unicode character string.
Definition: qstring.h:83
void setValue(int name, int value)
void append(const T &t)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
void setRenderableType(QEgl::API api)
const char * name
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
Q_CORE_EXPORT void qWarning(const char *,...)
bool reduceConfiguration()
#define TRUE
Synonym for true.
Definition: qglobal.h:1018
QString join(const QString &sep) const
Joins all the string list&#39;s strings into a single string with each element separated by the given sep...
Definition: qstringlist.h:162
QVarLengthArray< EGLint > props
static const struct @32 types[]
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
quint16 index
void setPixelFormat(QImage::Format pixelFormat)
int height() const
API
Definition: qegl_p.h:190
static void addTag(QString &str, const QString &tag)
void setDeviceType(int devType)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
int size() const